Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Add a button in a new column to all rows in a DataGrid

I have a DataGridView object:

dataGridView1.DataSource = an.peaks;

(an.peaks is a List<Point> object. Point type has 3 properties: x,y,z)

witch generates the next table on run-time: (Apparently I cant upload an Image yet because I'm a new user so I'll try to draw it :)

____|_x__|_y__|_z__|[new column ]
____|_11_|_12_|_13_|[text/button] <==\
____|_20_|_30_|_40_|[text/button] <== } Add text if something or button if something else.
____|_50_|_60_|_70_|[text/button] <==/

I would like to add buttons (as shown in the image/drawing) in a new column to each row that satisfying some condition. If the condition is not satisfied add some text instead.

Example: If the point already exist in the database show it's substance name (each point represent a substance). If not add a button "ADD" to the corresponding row that will add the new point to the database.

The conditions are not the problems - they are only for examples. The problem is adding the buttons/text to each row and the clicking event for the new button/s.

like image 658
Igor Avatar asked May 26 '12 19:05

Igor


1 Answers

This is actually quite simple to do using the DataGridView. What you need to do is:

Add column of type DataGridViewButtonColumn

DataGridViewButtonColumn is a standard DataGridView column type. It can be added through the designer but I generally prefer using code (usually in the form constructor).

DataGridViewButtonColumn col = new DataGridViewButtonColumn();
col.UseColumnTextForButtonValue = True;
col.Text = "ADD";
col.Name = "MyButton";
dataGridView1.Columns.Add(col);

Setting UseColumnTextForButtonValue true means that the Text property gets applied to all buttons giving them the "ADD" button text. You can also use DataPropertyName to point at a column in the grid's datasource to provide the button text, or you can even set each cell's value directly.

Change buttons to text

Once you have your button column you then want to turn particular buttons to text. You do this by replacing a cell of button type with one of text type. You can do this many places but one of the best is in the DataBindingComplete event handler - this event fires once the grid is bound and ready to display but before it is painted.

Below I simply grab the row with index 1 but you can also inspect each rows Value property.

void dataGridView1_DataBindingComplete(object sender,
    DataGridViewBindingCompleteEventArgs e)
{
    dataGridView1.Rows[1].Cells["MyButton"] = new DataGridViewTextBoxCell();
}

Respond to button clicks

The final part of the problem is responding to button clicks. This is a little bit cludgy - you need to either use the CellClick event or the EditingControlShowing event for the entire grid.

  • CellClick

    private void DataGridView1_CellClick(object sender,
        System.Windows.FormsDataGridViewCellEventArgs e) 
    { 
        if (DataGridView1.Columns[e.ColumnIndex].Name == "MyButton") 
        { 
            // button clicked - do some logic
        } 
    }
    
  • EditingControlShowing

    void dataGridView1_EditingControlShowing(object sender,
         DataGridViewEditingControlShowingEventArgs e)
    {
        if (e.Control is Button)
        {
            Button btn = e.Control as Button;
            btn.Click -= new EventHandler(btn_Click);
            btn.Click += new EventHandler(btn_Click);
        }
    }
    
    void btn_Click(object sender, EventArgs e)
    {
        int col = this.dataGridView1.CurrentCell.ColumnIndex;
        int row = this.dataGridView1.CurrentCell.RowIndex;
        // Rest of the logic goes here!
    } 
    

In your case the editing control approach is probably best since it won't respond to clicking on buttons that have been replaced with text. Also this way is more like how you respond to any other button on a form.

like image 53
David Hall Avatar answered Oct 21 '22 07:10

David Hall