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
dataGridView2.Columns.Insert(5, uninstallButtonColumn2)
todataGridView2.Columns.Insert(1, uninstallButtonColumn2)
if (e.ColumnIndex == 4)
toif (e.ColumnIndex == 0)
orderId = (string)dataGridView1.SelectedCells[0].OwningRow.Cells[1].Value;
toorderId = (string)dataGridView1.SelectedCells[0].OwningRow.Cells[2].Value;
at both the placeselse if (e.ColumnIndex == 5)
toelse 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 ofDataGridViewCellEventArgs
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 theDataGridView
orClick
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
Parsing Ftpwebrequest Listdirectorydetails Line
How to Get the Assembly File Version
Is There a Performance Impact When Calling Tolist()
Regex to Strip Line Comments from C#
How to Deserialize a Complex JSON Object in C# .Net
Mapping Object to Dictionary and Vice Versa
Get Month Name from Month Number
C# Elegant Way to Check If a Property's Property Is Null
How to Get More Than 1000 Records from a Directorysearcher
Combination of List<List<Int>>
Redirecting Standard Input of Console Application
Smoothly Connecting Circle Centers
Why Is .Contains Slow? Most Efficient Way to Get Multiple Entities by Primary Key