问题
Goal
My datagridview has two columns ([Question], [Answer]). Depending on the known question type (Yes/No Checkbox, Text Textbox, FileUpload Button) I want the column cell to have the respective control.
Example
Datagridview Rows:
- [Question] Do you smoke? [Answer] (YesNo Checkbox)
- [Question] How old are you? [Answer] (Text Textbox)
- [Question] Document upload [Answer] (FileUpload Button)
Work
I programmatically create my datagridviews.
Private Sub FormatQuestionDgv(ByVal dgv As DataGridView)
Dim ColQ As New DataGridViewTextBoxColumn
Dim ColA As New DataGridViewColumn
'Header text
ColQ.HeaderText = "Question"
ColA.HeaderText = "Answer"
'Name
ColQ.Name = "ColQ"
ColA.Name = "ColA"
'Widths
ColQ.AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill
ColA.AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill
'Add columns
With dgv.Columns
.Add(ColQ)
.Add(ColA)
End With
End Sub
Problem
As you can see in my work, the answer column is of DataGridViewColumn type. I do not know the question type at that moment. Therefore I declare it as a normal column instead of DataGridViewCheckBoxColumn, DataGridViewTextBoxColumn, DataGridViewButtonColumn...
Since those are not the same type as DataGridViewColumn, I get the following error:
How do I go about adding different control types in 1 DataGridViewColumn? Is it even possible?
回答1:
Have you looked at these:
Mixing cell types in a DataGridViewColumn
DataGridview cells of one column can't have different type
http://social.msdn.microsoft.com/Forums/windows/en-US/148b232b-ce8c-4c49-b35d-50d8a5c448d1/different-cell-types-in-a-datagridview-column
Following from the MSDN article...
There are two ways to do this:
- Cast a
DataGridViewCellto a certain cell type that exists. For example, convert aDataGridViewTextBoxCelltoDataGridViewComboBoxCelltype. - Create a control and add it into the controls collection of
DataGridView, set its location and size to fit the cell that to be host.
Here's some sample code which illustrates these tricks:
private void Form5_Load(object sender, EventArgs e)
{
DataTable dt = new DataTable();
dt.Columns.Add("name");
for (int j = 0; j < 10; j++)
{
dt.Rows.Add("");
}
this.dataGridView1.DataSource = dt;
this.dataGridView1.Columns[0].Width = 200;
/*
* First method : Convert to an existed cell type such ComboBox cell,etc
*/
DataGridViewComboBoxCell ComboBoxCell = new DataGridViewComboBoxCell();
ComboBoxCell.Items.AddRange(new string[] { "aaa","bbb","ccc" });
this.dataGridView1[0, 0] = ComboBoxCell;
this.dataGridView1[0, 0].Value = "bbb";
DataGridViewTextBoxCell TextBoxCell = new DataGridViewTextBoxCell();
this.dataGridView1[0, 1] = TextBoxCell;
this.dataGridView1[0, 1].Value = "some text";
DataGridViewCheckBoxCell CheckBoxCell = new DataGridViewCheckBoxCell();
CheckBoxCell.Style.Alignment = DataGridViewContentAlignment.MiddleCenter;
this.dataGridView1[0, 2] = CheckBoxCell;
this.dataGridView1[0, 2].Value = true;
/*
* Second method : Add control to the host in the cell
*/
DateTimePicker dtp = new DateTimePicker();
dtp.Value = DateTime.Now.AddDays(-10);
//add DateTimePicker into the control collection of the DataGridView
this.dataGridView1.Controls.Add(dtp);
//set its location and size to fit the cell
dtp.Location = this.dataGridView1.GetCellDisplayRectangle(0, 3,true).Location;
dtp.Size = this.dataGridView1.GetCellDisplayRectangle(0, 3,true).Size;
}
回答2:
The other answers are way to difficult and error prone. Why not just add the desired row programmatically?
Example:
Using the designer, create a form with a DataGridView, and two columns: one for the question and one for the answer.
private DataGridView dataGridView3;
private DataGridViewTextBoxColumn columnQuestion;
private DataGridViewTextBoxColumn columnAnswer;
In my class, I created the enum for the answer type
public enum AnswerType
{
Text,
YesNo,
LoadFile,
Combo,
};
The method to create a question cell is simple
private DataGridViewCell CreateQuestionCell(string question)
{
return new DataGridViewTextBoxCell()
{
ValueType = typeof(string),
Value = question,
};
}
The method to create an answer cell has a parameter indicating the desired answer type:
private DataGridViewCell CreateAnswerCell(AnswerType answerType)
{
// type of column depends on rowIndex
DataGridViewCell cell;
switch (answerType)
{
case AnswerType.YesNo: // Create a checkbox cell
cell = new DataGridViewCheckBoxCell()
{
ValueType = typeof(bool),
Value = false,
};
break;
case AnswerType.LoadFile: // Create a Button cell
cell = new DataGridViewButtonCell()
{
ValueType = typeof(string),
Value = "Load!",
};
break;
case AnswerType.Combo: // Create a Combo Cell
var selectableValues = Enumerable.Range(0, 4);
var comboItems = Enumerable.Range(0, 100);
cell = new DataGridViewComboBoxCell()
{
DataSource = new BindingList<int>(comboItems.ToList()),
};
break;
default: // Create a Text cell
cell = new DataGridViewTextBoxCell()
{
ValueType = typeof(string),
Value = "<please enter name>",
};
break;
}
return cell;
}
Upon request add a Row, containing a question cell and an answer cell:
private void AddRow(string question, AnswerType answerType)
{
DataGridViewRow row = new DataGridViewRow();
row.Cells.Add(this.CreateQuestionCell(question));
row.Cells.Add(this.CreateAnswerCell(answerType));
row.Cells[columnQuestion.Index].ReadOnly = true;
this.dataGridView3.Rows.Add(row);
}
To test I created four buttons and handlers to add rows:
private Button buttonCheckbox;
private Button buttonAction;
private Button buttonCombo;
private Button buttonText;
private void OnButtonCheckbox(object sender, EventArgs e)
{
this.AddRow("Do you smoke", AnswerType.YesNo);
}
private void OnButtonText(object sender, EventArgs e)
{
this.AddRow("Name", AnswerType.Text);
}
private void OnButtonCombo(object sender, EventArgs e)
{
this.AddRow("Age?", AnswerType.Combo);
}
private void OnButtonAction(object sender, EventArgs e)
{
this.AddRow("Document upload", AnswerType.LoadFile);
}
Et voilà, ça marche! Simple comme bonjour!
回答3:
DataGridViewCellStyle styl_Column = new DataGridViewCellStyle();
if (_myColumnCollection[i].TypeColumn == TypColumn.CheckBox)
{
dtv_information.Columns.Add(chk_clmn);
styl_Column.NullValue = false;
}
styl_Column.NullValue = false;
来源:https://stackoverflow.com/questions/18045248/adding-different-datagridview-cell-types-to-a-column