将不同的DataGridView单元格类型添加到列

目标

我的datagridview有两列([问题],[答案])。 根据已知的问题类型是/否 复选框文本文本 文件上载 按钮 ),我希望列单元格具有相应的控件

Datagridview行:

  1. [问题]你吸烟吗? [答案]( YesNo Checkbox
  2. [问题]你多大了? [答案]( 文字文字
  3. [问题]文件上传[答案]( FileUpload 按钮

工作

我以编程方式创建我的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 

问题

正如您在我的工作中所看到的,答案列是DataGridViewColumn类型。 我当时不知道问题的类型。 因此我将其声明为普通列而不是DataGridViewCheckBoxColumnDataGridViewTextBoxColumnDataGridViewButtonColumn

由于这些类型与DataGridViewColumn ,我收到以下错误:

错误的类型错误

如何在1 DataGridViewColumn中添加不同的控件类型? 它甚至可能吗?

你看过这些:

在DataGridViewColumn中混合单元格类型

一列的DataGridview单元格不能有不同的类型

http://social.msdn.microsoft.com/Forums/windows/en-US/148b232b-ce8c-4c49-b35d-50d8a5c448d1/different-cell-types-in-a-datagridview-column

以下是MSDN文章……

有两种方法可以做到这一点:

  1. DataGridViewCell转换为存在的某个单元格类型。 例如,将DataGridViewTextBoxCell转换为DataGridViewComboBoxCell类型。
  2. 创建一个控件并将其添加到DataGridView的控件集合中,设置其位置和大小以适合要作为主机的单元格。

这里有一些示例代码说明了这些技巧:

 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; } 

其他答案是困难和容易出错的方式。 为什么不以编程方式添加所需的行?

例:

使用设计器,使用DataGridView创建一个表单,并使用两列:一列用于问题,另一列用于答案。

 private DataGridView dataGridView3; private DataGridViewTextBoxColumn columnQuestion; private DataGridViewTextBoxColumn columnAnswer; 

在我的class上,我为答案类型创建了枚举

 public enum AnswerType { Text, YesNo, LoadFile, Combo, }; 

创建问题单元的方法很简单

 private DataGridViewCell CreateQuestionCell(string question) { return new DataGridViewTextBoxCell() { ValueType = typeof(string), Value = question, }; } 

创建答案单元格的方法有一个参数,指示所需的答案类型:

 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(comboItems.ToList()), }; break; default: // Create a Text cell cell = new DataGridViewTextBoxCell() { ValueType = typeof(string), Value = "", }; break; } return 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); } 

为了测试我创建了四个按钮和处理程序来添加行:

 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); } 

Etvoilà,çamarche! 简单的纪念bonjour!

 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;