How to Handle Click Event in Button Column in Datagridview

How to handle click event in Button Column in Datagridview?

You've added a button to your DataGridView and you want to run some code when it's clicked.

Easy peasy - just follow these steps:

Don'ts

First, here's what NOT to do:

I would avoid the suggestions in some of the other answers here and even provided by the documentation at MSDN to hardcode the column index or column name in order to determine if a button was clicked. The click event registers for the entire grid, so somehow you need to determine that a button was clicked, but you should not do so by assuming that your button lives in a particular column name or index... there's an easier way...

Also, be careful which event you want to handle. Again, the documentation and many examples get this wrong. Most examples handle the CellClick event which will fire:

when any part of a cell is clicked.

...but will also fire whenever the row header is clicked. This necessitates adding extra code simply to determine if the e.RowIndex value is less than 0

Instead handle the CellContentClick which only occurs:

when the content within a cell is clicked

For whatever reason, the column header is also considered 'content' within a cell, so we'll still have to check for that below.

Dos

So here's what you should do:

First, cast the sender to type DataGridView to expose it's internal properties at design time. You can modify the type on the parameter, but that can sometimes make adding or removing handlers tricky.

Next, to see if a button was clicked, just check to make sure that the column raising the event is of type DataGridViewButtonColumn. Because we already cast the sender to type DataGridView, we can get the Columns collection and select the current column using e.ColumnIndex. Then check if that object is of type DataGridViewButtonColumn.

Of course, if you need to distinguish between multiple buttons per grid, you can then select based on the column name or index, but that shouldn't be your first check. Always make sure a button was clicked first and then handle anything else appropriately. In most cases where you only have a single button per grid, you can jump right off to the races.

Putting it all together:

C#

private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
var senderGrid = (DataGridView)sender;

if (senderGrid.Columns[e.ColumnIndex] is DataGridViewButtonColumn &&
e.RowIndex >= 0)
{
//TODO - Button Clicked - Execute Code Here
}
}

VB

Private Sub DataGridView1_CellContentClick(sender As System.Object, e As DataGridViewCellEventArgs) _
Handles DataGridView1.CellContentClick
Dim senderGrid = DirectCast(sender, DataGridView)

If TypeOf senderGrid.Columns(e.ColumnIndex) Is DataGridViewButtonColumn AndAlso
e.RowIndex >= 0 Then
'TODO - Button Clicked - Execute Code Here
End If

End Sub


Update 1 - Custom Event

If you wanted to have a little bit of fun, you can add your own event to be raised whenever a button is clicked on the DataGrid. You can't add it to the DataGrid itself, without getting messy with inheritance etc., but you can add a custom event to your form and fire it when appropriate. It's a little more code, but the upside is that you've separated out what you want to do when a button is clicked with how to determine if a button was clicked.

Just declare an event, raise it when appropriate, and handle it. It will look like this:

Event DataGridView1ButtonClick(sender As DataGridView, e As DataGridViewCellEventArgs)

Private Sub DataGridView1_CellContentClick(sender As System.Object, e As DataGridViewCellEventArgs) Handles DataGridView1.CellContentClick
Dim senderGrid = DirectCast(sender, DataGridView)
If TypeOf senderGrid.Columns(e.ColumnIndex) Is DataGridViewButtonColumn AndAlso e.RowIndex >= 0 Then
RaiseEvent DataGridView1ButtonClick(senderGrid, e)
End If
End Sub

Private Sub DataGridView1_ButtonClick(sender As DataGridView, e As DataGridViewCellEventArgs) Handles Me.DataGridView1ButtonClick
'TODO - Button Clicked - Execute Code Here
End Sub


Update 2 - Extended Grid

What would be great is if we were working with a grid that just did these things for us. We could answer the initial question easily: you've added a button to your DataGridView and you want to run some code when it's clicked. Here's an approach that extends the DataGridView. It might not be worth the hassle of having to deliver a custom control with every library, but at least it maximally reuses the code used for determining if a button was clicked.

Just add this to your assembly:

Public Class DataGridViewExt : Inherits DataGridView

Event CellButtonClick(sender As DataGridView, e As DataGridViewCellEventArgs)

Private Sub CellContentClicked(sender As System.Object, e As DataGridViewCellEventArgs) Handles Me.CellContentClick
If TypeOf Me.Columns(e.ColumnIndex) Is DataGridViewButtonColumn AndAlso e.RowIndex >= 0 Then
RaiseEvent CellButtonClick(Me, e)
End If
End Sub

End Class

That's it. Never touch it again. Make sure your DataGrid is of type DataGridViewExt which should work exactly the same as a DataGridView. Except it will also raise an extra event that you can handle like this:

Private Sub DataGridView1_ButtonClick(sender As DataGridView, e As DataGridViewCellEventArgs) _
Handles DataGridView1.CellButtonClick
'TODO - Button Clicked - Execute Code Here
End Sub

Adding button in datagridView not working onClick event

you can use is operator for checking that: "is your cell a button of other"

and use CellContentClick instead CellClick, because if user click on padding of your button, your event don't raise and wait for clicking ON your button.

Therefor, you can use this event

private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
if (dataGridView1[e.ColumnIndex,e.RowIndex] is DataGridViewButtonCell)
(dataGridView1[e.ColumnIndex, e.RowIndex] as DataGridViewButtonCell).Value = "You Clicked Me...";
}

Datagridview Button Click event not firing

Corrections below

  1. dataGridView2.Columns.Insert(5, uninstallButtonColumn2) to dataGridView2.Columns.Insert(1, uninstallButtonColumn2)

  2. if (e.ColumnIndex == 4) to if (e.ColumnIndex == 0)

  3. orderId = (string)dataGridView1.SelectedCells[0].OwningRow.Cells[1].Value; to orderId = (string)dataGridView1.SelectedCells[0].OwningRow.Cells[2].Value; at both the places

  4. else if (e.ColumnIndex == 5) to else if (e.ColumnIndex == 1)

Programmatically perform click on a DataGridView Button Cell from another Button

You can use either of the following options:

  • Calling the event handler of CellContentClick like a normal method by creating an instance of DataGridViewCellEventArgs and pass it to the event handler method.
  • Or put the whole logic inside a method and call that method whenever you need, from CellContentClick of the DataGridView or Click of the button.

VB.NET

Example 1 - Perform Click for DataGrdiView Button Cell by calling the event handler

To programmatically click on button in specific row, you can call the method that you created as event handler of CellContentClick event, using suitable DataGridViewCellEventArgs as e and your DataGridView as sender:

Private Sub AnotherButton_Click(sender As Object, e As EventArgs) _
Handles AnotherButton.Click
' zero based ColumnIndex of your button column= 3 (for example)
' zero based RowIndex that you want to click on its button column = 2 (for example)
Dim arg = New DataGridViewCellEventArgs(3, 2)
DataGridView1_CellContentClick(DataGridView1, arg)
End Sub

Private Sub DataGridView1_CellContentClick(sender As Object, _
e As DataGridViewCellEventArgs) Handles DataGridView1.CellContentClick
MessageBox.Show(e.RowIndex.ToString())
End Sub

Example 2 - Putting the logic in another method and call the method when you need

As another option you can put the logic related to click on a cell button in a method, dependent from Cell and Row objects and only pass suitable values to that method. Then you can call the method wherever you need.

Private Sub DoSomething(rowIndex as Integer, columnIndex as Integer)
MessageBox.Show(rowIndex.ToString())
End Sub

Private Sub AnotherButton_Click(sender As Object, e As EventArgs) _
Handles AnotherButton.Click
' zero based ColumnIndex of your button column= 3 (for example)
' zero based RowIndex that you want to click on its button column = 2 (for example)
DoSomething(2, 3)
End Sub

Private Sub DataGridView1_CellContentClick(sender As Object, _
e As DataGridViewCellEventArgs) Handles DataGridView1.CellContentClick
DoSomething(e.RowIndex, e.ColumnIndex)
End Sub

C#

Example 1 - Perform Click for DataGrdiView Button Cell by calling the event handler

To programmatically click on button in specific row, you can call the method that you created as event handler of CellContentClick event, using suitable DataGridViewCellEventArgs as e and your DataGridView as sender:

private void anotherButton_Click(object sender, EventArgs e)
{
' zero based ColumnIndex of your button column= 3 (for example)
' zero based RowIndex that you want to click on its button column = 2 (for example)
var arg = new DataGridViewCellEventArgs(3, 2);
aataGridView1_CellContentClick(dataGridView1, arg);
}

private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
MessageBox.Show(e.RowIndex.ToString());
}

Example 2 - Putting the logic in another method and call the method when you need

As another option you can put the logic related to click on a cell button in a method, dependent from Cell and Row objects and only pass suitable values to that method. Then you can call the method wherever you need.

private void DoSomething(int rowIndex, int columnIndex)
{
MessageBox.Show(rowIndex.ToString());
}

private void anotherButton_Click(object sender, EventArgs e)
{
' zero based ColumnIndex of your button column= 3 (for example)
' zero based RowIndex that you want to click on its button column = 2 (for example)
DoSomething(2, 3);
}

private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
DoSomething(e.RowIndex, e.ColumnIndex);
}

Manually fire button click event in DataGridView

I do not think there is a specific event available to handle when a DataGridViewButtonColumn cell is clicked. The DataGridView’s Cell_Clicked and CellContentClicked events get fired.

I was not able to get the delay of clicking into the DataGridView once then having to click again to fire the button. When I clicked on the DataGridView button cell, the Cell_Clicked event was immediately fired. Changing the DataGridView’s EditMode made no difference. The code below simply identifies WHICH cell was clicked from the Cell_Clicked event. If the cell clicked was a button column (1 or 2), then I call a created method ButtonHandler to handle which button was pressed and to continue on to the correct button method. Hope this helps.

private void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e) {
if (e.ColumnIndex == 1 || e.ColumnIndex == 2) {
// one of the button columns was clicked
ButtonHandler(sender, e);
}
}

private void ButtonHandler(object sender, DataGridViewCellEventArgs e) {
if (e.ColumnIndex == 1) {
MessageBox.Show("Column 1 button clicked at row: " + e.RowIndex + " Col: " + e.ColumnIndex + " clicked");
// call method to handle column 1 button clicked
// MethodToHandleCol1ButtonClicked(e.RowIndex);
}
else {
MessageBox.Show("Column 2 button clicked at row: " + e.RowIndex + " Col: " + e.ColumnIndex + " clicked");
// call method to handle column 2 button clicked
// MethodToHandleCol2ButtonClicked(e.RowIndex);
}
}

Finding the click event of DGV button column and transferring to another form

This is answered on the MSDN page for the DataGridViewButtonColumn.

You need to handle either the CellClick or CellContentClick events of the DataGridView.

To attach the handler:

dataGridView1.CellClick += new DataGridViewCellEventHandler(dataGridView1_CellClick);

And the code in the method that handles the evend

void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e)
{
// Check that the button column was clicked
if (dataGridView1.Columns[e.ColumnIndex].Name == "MyButtonColumn")
{
// Here you call your method that deals with the row values
// you can use e.RowIndex to find the row

// I also use the row's databounditem property to get the bound
// object from the DataGridView's datasource - this only works with
// a datasource for the control but 99% of the time you should use
// a datasource with this control
object item = dataGridView1.Rows[e.RowIndex].DataBoundItem;

// I'm also just leaving item as type object but since you control the form
// you can usually safely cast to a specific object here.
YourMethod(item);
}
}

How to call a datagridview event with a click of a button?

Since you are not using anything related to sender object and event args then the solution is as simple as this

kryptonDataGridView1_CellDoubleClick(null, null);

the method kryptonDataGridView1_CellDoubleClick is just a function like all other functions in C# and you can call it explicitly.

if you want more control you can do it like

private void kryptonbtnEdit_Click(object sender, EventArgs e)
{
//set parameters of your event args
var eventArgs = new DataGridViewCellEventArgs(yourColumnIndex, yourRowIndex);

// or setting the selected cells manually before executing the function
kryptonDataGridView1.Rows[yourRowIndex].Cells[yourColumnIndex].Selected = true;

kryptonDataGridView1_CellDoubleClick(sender, eventArgs);
}

Note that events can only be raised from code within the control that declares the event. This does not fire the CellDoubleClick event, it just execute the function kryptonDataGridView1_CellDoubleClick that you register it to be executed when CellDoubleClick event fires. If you have registered other methods to be invoked when CellDoubleClick fired then you should execute them too explicitly.

Keep in mind that you can always create a derived class from KryptonDataGridView and handle these things internally and provide an API for yourself to use it later or in many complex scenarios you can get the underlying method which fires the event internally in the control using reflection and fire it manually.



Related Topics



Leave a reply



Submit