向 Winforms DataGridView 添加按钮

9
有没有办法在C#的Winforms DataGridView单元格中添加控件(例如按钮)?
(我的目的是将各种类型的控件放置在网格的不同单元格中...)

https://dev59.com/r1fUa4cB1Zd3GeqPIHFN - Davide Piras
3个回答

8

您可以像这样做...

有两种方法可以实现此目的:

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

1
虽然第二种方法确实显示了控件,但当滚动单元格时它保持静态状态 - 有没有办法将新控制锁定到底层单元格? - Niall
第一种方法效果很好,第二种方法在滚动时会导致控件“掉出”网格。我猜你可以使用格式事件将其移回来。 - Matthew Lock

6
DataGridViewButtonColumn 是一种提供的列类型,其中包含可点击的按钮。您可以将自己的控件添加到单元格中:

http://msdn.microsoft.com/en-us/library/7tas5c80.aspx

请记住,这并不总是简单的,但我曾经看到有人将整个 DataGridView 放入一个单元格中——看起来很奇怪。
还有其他提供的列:
DataGridViewButtonColumn
DataGridViewCheckBoxColumn
DataGridViewComboBoxColumn
DataGridViewImageColumn
DataGridViewLinkColumn
DataGridViewTextBoxColumn

您可以在Visual Studio的设计器中的列编辑器中更改这些内容,或将它们添加到代码中的“Columns”集合中。

啊,你的意思是我可以将任何类型的控件添加到DataGridViewButtonColumn中?当我偶然发现这一点时,我以为它只是一个充满按钮的列;-) - Boris
@Boris 不是针对按钮列,你可以创建一个列类型来托管任何控件,并将该列类型添加到网格中。例如,您可以创建一个DataGridViewNumericUpDownColumn,它托管一个NumericUpDown控件。该列被编码为托管特定控件类型,而不是运行时决策。 - Adam Houldsworth
但我认为仍然存在一个误解:使用这种方法,整个列是否都有相同类型的控件?因为我想在每个单元格中拥有不同类型的控件。 - Boris
是的,在这种方法中,整个列都会受到影响,因为通常在网格中整个列包含相同的数据类型。我没有看到过,也不知道有什么解决方案可以允许单个单元格包含不同的编辑控件。 - Adam Houldsworth
@Boris 实际上,你可以定义一个 DataGridViewPanelColumn,它具有根据需要向面板添加和删除子控件的能力。虽然这不一定是最干净或最简单的方法来实现它。 - Adam Houldsworth

-3

我会在设计器中添加它,并创建一个模板字段。这是一个简单的方法,可以将任何你想要的东西放入 datagridview。

示例

<asp:DataGrid ID="somedatagrid" runat="server">
    <Columns>
        <asp:TemplateColumn>
            <ItemTemplate>
                <asp:Button ID="somebutton" runat="server" Text="some button" />
            </ItemTemplate>
        </asp:TemplateColumn>
    </Columns>
</asp:DataGrid>

2
很遗憾,这个问题是关于winforms而不是.NET网页的。 - Zorgarath

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