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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18045248/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 11:07:51  来源:igfitidea点击:

Adding Different DataGridView Cell Types to a Column

c#vb.netdatagridviewcells

提问by Alex

Goal

目标

My datagridview has two columns ([Question], [Answer]). Depending on the known question type(Yes/NoCheckbox, TextTextbox, FileUploadButton) I want the column cell to have the respective control.

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

Example

例子

Datagridview Rows:

数据网格视图行:

  1. [Question] Do you smoke? [Answer] (YesNoCheckbox)
  2. [Question] How old are you? [Answer] (TextTextbox)
  3. [Question] Document upload [Answer] (FileUploadButton)
  1. [问题] 你抽烟吗?[答案](是否复选框
  2. [问题] 你几岁了?[答案](文本文本
  3. [问题] 文件上传 [答案] ( 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 DataGridViewColumntype. I do not know the question type at that moment. Therefore I declare it as a normal column instead of DataGridViewCheckBoxColumn, DataGridViewTextBoxColumn, DataGridViewButtonColumn...

正如你在我的作品中看到的,答案栏是DataGridViewColumn类型的。我当时不知道问题类型。因此,我将其声明为普通列而不是DataGridViewCheckBoxColumn, DataGridViewTextBoxColumn, DataGridViewButtonColumn...

Since those are not the same type as DataGridViewColumn, I get the following error:

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

Wrong Type Error

错误类型错误

How do I go about adding different control types in 1 DataGridViewColumn? Is it even possible?

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

采纳答案by puneet

Have you looked at these:

你看过这些:

Mixing cell types in a DataGridViewColumn

在 DataGridViewColumn 中混合单元格类型

DataGridview cells of one column can't have different type

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

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

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...

遵循 MSDN 文章...

There are two ways to do this:

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

  1. Cast a DataGridViewCellto a certain cell type that exists. For example, convert a DataGridViewTextBoxCellto DataGridViewComboBoxCelltype.
  2. 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.
  1. 将 aDataGridViewCell转换为存在的某个单元格类型。例如,将 a 转换DataGridViewTextBoxCellDataGridViewComboBoxCell类型。
  2. 创建一个控件并将其添加到 的控件集合中 DataGridView,设置其位置和大小以适合要托管的单元格。

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

回答by sina

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;

回答by Harald Coppoolse

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.

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

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!

Et voilà, ? a Marche!简单的来吧!