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

6

目标

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

例子

Datagridview行:

  1. [问题] 你抽烟吗? [答案] (YesNo 复选框)
  2. [问题] 你多大了? [答案] (文本 文本框)
  3. [问题] 文档上传 [答案] (文件上传 按钮)

工作

我以编程方式创建我的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不同,因此我会收到以下错误:

Wrong Type Error

如何在1个DataGridViewColumn中添加不同类型的控件?这是否可能?

3个回答

9

您看过这些内容吗:

混合使用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;
}

是的,我之前搜索过那些链接,但我认为有更简单的方法来完成。 - Alex
我认为MSDN链接是一个非常直接的方法。 - puneet
是的,我直接在用户界面上展示它,以便用户可以回答问题。是的,MDSN链接很容易跟进。谢谢。 - Alex
这在VS 2013中不起作用。我得到了所有文本框单元格。 - Adam Bruss
@puneet,如果datagridview在另一个窗体上,则第一种方法无法解决问题。而第二种方法存在datagridview滚动条的问题。有没有针对这些问题的解决方案? - Lati
1
我不知道你们其他人怎么样,但在我添加了以下几行代码之前,我一直遇到“单元格的格式化值类型错误”的错误: CheckBoxCell.IndeterminateValue = false; CheckBoxCell.FalseValue = false; CheckBoxCell.TrueValue = true;或者只需使用CheckBoxCell.ValueType = typeof(bool); - B H

7
其他答案太复杂且容易出错。 按要求添加所需的单元格类型更加简单。 示例: 使用设计器创建一个带有DataGridView和两列的表单:一个用于问题,一个用于答案。
private DataGridView dataGridView3;
private DataGridViewTextBoxColumn columnQuestion;
private DataGridViewTextBoxColumn columnAnswer;

在我的班级中,我创建了用于答案类型的枚举

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

我将创建两种方法:一种用于创建包含问题的单元格,另一种用于创建符合答案格式的单元格。
创建问题单元格的方法很简单:
private DataGridViewCell CreateQuestionCell(string question)
{
    return new DataGridViewTextBoxCell()
    {
        ValueType = typeof(string),
        Value = question,
        ReadOnly = true,       // questions can't be edited
    };
}

创建答案单元格的方法有一个参数,用于指定所需的答案类型:
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;
}

当请求添加一行时,包含一个问题单元格和一个答案单元格:

private void AddRow(string question, AnswerType answerType)
{
    DataGridViewRow row = new DataGridViewRow();
    row.Cells.Add(this.CreateQuestionCell(question));
    row.Cells.Add(this.CreateAnswerCell(answerType));
    this.dataGridView1.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);
}

现在,它已经可以运行了!就像打招呼一样简单!


Haha merci!! ;) - Alex

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接