如何在DataGridView中的某些(而非全部)列中添加按钮?

时间:2010-11-23 23:35:29

标签: c# winforms datagridview

我正在尝试更新此DataGridView对象,以便在值==“bob”时,其名称旁边的列中会有一个按钮,否则我不希望出现任何按钮。

DataGridViewTextBoxColumn valueColumn = new DataGridViewTextBoxColumn();
DataGridViewButtonColumn buttonColumn = new DataGridViewButtonColumn();

buttonColumn.ReadOnly = true;
buttonColumn.Visible = false;

this.dgv.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
valueColumn,
buttonColumn,
});

//elsewhere...

if(value == "bob")
{
    Button button = new Button()
    {
        Text = "null",
    };

    index = dgv.Rows.Add(value, button);
    DataGridViewButtonCell buttonCell = dgv.Rows[index].Cells[2] as DataGridViewButtonCell;
    buttonCell.Visible = true;
}
else
{
    dgv.Rows.Add(value);
}

但是,因为我无法在单元格上设置Visible,所以这不起作用。有没有办法只在行中添加一个按钮= Value ==“bob”?

3 个答案:

答案 0 :(得分:4)

这是我之前用过的一个简洁的小黑客:

使用DataGridViewTextBoxColumn而不是使用DataGridViewButtonColumn,并在适当的位置添加DataGridViewButtonCell。

e.g。

    private void button1_Click(object sender, EventArgs e)
    {
        // Iterate through each of the rows.
        for (int i = 0; i < dgv.RowCount - 1; i++)
        {
            if (dgv.Rows[i].Cells[0].Value.ToString() == "bob")
            {
                // Here is the trick.
                var btnCell = new DataGridViewButtonCell();
                dgv.Rows[i].Cells[1] = btnCell;
            }
        }
    }

在上面的示例中,我有两个DataGridViewTextBoxColumns并遍历按钮单击事件中的每一行。我检查第一列是否包含“bob”,如果包含“bob”,我会在其旁边的列中添加一个按钮。您可以根据需要使用此技巧(即按钮单击,RowsAdded事件,CellEndEdit事件等)。以不同方式进行实验。希望这有助于某人!

答案 1 :(得分:3)

这里有两种可能,一种是丑陋的,一种来自MSDN。

丑陋:在运行时向DGV添加按钮

执行以下操作:
- 将未绑定的DataGridViewTextBoxColumn添加到您的DGV。注意它是DGV中的索引值;这是你放按钮的地方 - 使用您的DGV的CellFormatting事件,如下所示:

    private void dataGridView1_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e) {
        if (e.ColumnIndex == 0) {  // Assumes column 0 has the data that determines if a button should be displayed.
            if (e.Value.ToString() == "bob") {  // Test if a button should be displayed on row.
                // Create a Button and add it to our DGV.
                Button cellButton = new Button();
                // Do something to identify which row's button was clicked.  Here I'm just storing the row index.
                cellButton.Tag = e.RowIndex;
                cellButton.Text = "Hello bob";
                cellButton.Click += new EventHandler(cellButton_Click);
                dataGridView1.Controls.Add(cellButton);
                // Your ugly button column is shown here as having an index value of 3.
                Rectangle cell = this.dataGridView1.GetCellDisplayRectangle(3, e.RowIndex, true);
                cellButton.Location = cell.Location;
            }
        }
    }

当用户点击该按钮时,将触发cellButton_Click事件。这是一些测试代码:

    void cellButton_Click(object sender, EventArgs e) {
        Console.WriteLine("Hello from row: {0}", ((Button) sender).Tag);
    }

正如你所看到的,这不是很精致。我的基础是我发现的一个更加丑陋的样本。我相信你可以根据自己的需要进行修改。

来自MSDN:滚动自己的(扩展)DataGridViewButtonColumn,有条件地显示禁用的按钮。

有关此选项,请参阅How to: Disable Buttons in a Button Column in the Windows Forms DataGridView Control

当然,此选项实际上删除任何按钮,只是有条件地禁用它们。但是,对于您的应用程序,这可能会更好。

答案 2 :(得分:1)

您可以在细胞绘画事件上处理细胞绘画:

private void dgv_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
{
     if(e.RowIndex>=0 && e.ColumnIndex == indexOfButtonColumn  && value[e.RowIndex] != "bob")
     {
           e.Paint(e.ClipBounds, DataGridViewPaintParts.All & ~DataGridViewPaintParts.ContentForeground & ~DataGridViewPaintParts.ContentBackground); 
           e.Handled = true;      
     }
}