How to get a CheckBox in a Winforms DataGridView to react to the first click

I had this problem today. It looks very simple, but actually took me a while to find a solution. The problem is: I have a Winforms DataGridView, and its first column is an unbound CheckBox column which is used to select/unselect a row. I want to hook up the check/uncheck event so that I can execute some logic after a row is selected or unselected. As this is Winforms, there is no way I can hook up an event from a control’s child element. But, it is quite obvious that we can hook up DataGridView’s OnCellvalueChanged event and put the logic there. So I had some code like this:

private void EmployeesGrid_OnCellValueChanged(object sender,  

     DataGridViewCellEventArgs e)

{

     if (e.ColumnIndex == 0 && e.RowIndex > -1)

     {

        bool selected = (bool)_gvEmployees[e.ColumnIndex, e.RowIndex].Value;

        _gvEmployees.Rows[e.RowIndex].DefaultCellStyle.BackColor =

selected ? Color.Yellow : Color.White;

     }

}

 

Here, for demonstration, I just simple change the background color of a row depending on if the checkbox column is checked or not. It all works fine except the background color won’t change until you move your mouse cursor out of the cell. The reason for that is OnCellvalueChanged event won’t fire until the DataGridView thinks you have completed editing. This makes senses for a TextBox Column, as OnCellvalueChanged wouldn’t broth to fire for each key strike, but it doesn’t for a CheckBox.

 

After trying a few different events, I finally find a workaround, and it is very simple. I just need to hook up on CellMouseUp event and explicitly exit edit mode there. Some sample code is here:

 

private void EmployeesGrid_OnCellMouseUp(object sender,  

     DataGridViewCellMouseEventArgs e)

{

     if (e.ColumnIndex == 0 && e.RowIndex > -1)

     {

        _gvEmployees.EndEdit();

     }

}

Print | posted on Sunday, September 7, 2008 8:29 PM

Feedback

# re: How to get a CheckBox in a Winforms DataGridView to react to the first click

Left by Kevin at 12/3/2008 2:54 AM
Gravatar Converted the code to VB.NET and threw my event after the "end edit" and it worked the value is validated right after the click instead of when the next cell is selected.

Thanks a million you have saved me so much hassle.

Thanks
Kev

# re: How to get a CheckBox in a Winforms DataGridView to react to the first click

Left by rg at 4/30/2009 7:42 PM
Gravatar How did you hook up the "OnCellMouseUp" Cause it never fires

# re: How to get a CheckBox in a Winforms DataGridView to react to the first click

Left by Jean at 6/15/2009 10:21 AM
Gravatar Well done, you have just saved me a lot of time !

here it is in vb.net

Private Sub dgrTrades_CellValueChanged(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles dgrTrades.CellValueChanged

End Sub

Private Sub dgrTrades_CellMouseUp(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DataGridViewCellMouseEventArgs) Handles dgrTrades.CellMouseUp
If e.RowIndex > -1 Then
dgrTrades.EndEdit()
End If


End Sub

# re: How to get a CheckBox in a Winforms DataGridView to react to the first click

Left by Michaël Van Laere at 6/22/2009 10:57 PM
Gravatar What if the user changes the state of the checkbox by using the keyboard?

# re: How to get a CheckBox in a Winforms DataGridView to react to the first click

Left by Drishty at 10/26/2009 4:52 AM
Gravatar Thanks, It helps a lot...

# re: How to get a CheckBox in a Winforms DataGridView to react to the first click

Left by Arapi at 11/23/2009 4:30 AM
Gravatar You dont actually need to code CellMouseUp event because if the user is using keyboard instead of the mosue the logic will not execute. You can write your logic in CellContentClick event, like this:
Private Sub dg_CellContentClick(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles dg.CellContentClick
If e.ColumnIndex = 0 AndAlso Not dg.Rows(e.RowIndex).IsNewRow Then
dg.EndEdit()
' logic goes here
End Sub

# re: How to get a CheckBox in a Winforms DataGridView to react to the first click

Left by Alex at 12/7/2009 8:19 AM
Gravatar I've got it working with such a 'workaround' (tnx to all chaotic info on the net and a half-a-hour of... experiments):

LocalSmGrid - just a normal DataGridView

private void LocalSmGrid_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
if (LocalSmGrid.CurrentCell.OwningColumn.Name.ToLower() == "ok") //if the clicked cell name = "ok"
{
CheckState cs = (CheckState)LocalSmGrid.CurrentCell.EditedFormattedValue;
if (cs == CheckState.Checked) { MessageBox.Show("now Checked"); }
else if (cs == CheckState.Unchecked) { MessageBox.Show("now Unchecked"); }
else if (cs == CheckState.Indeterminate) { MessageBox.Show("now Indeterminate"); }
}
}

# re: How to get a CheckBox in a Winforms DataGridView to react to the first click

Left by Alex at 12/7/2009 8:37 AM
Gravatar oh forgot
LocalSmGrid.CommitEdit(DataGridViewDataErrorContexts.Commit);
before the first "if" :)

# re: How to get a CheckBox in a Winforms DataGridView to react to the first click

Left by Alex at 12/7/2009 8:50 AM
Gravatar mm... actually.. er... now I feel myself like an idiot - committing changes calls an appropriate event (that we actually need), and it is

private void LocalSmGrid_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
LocalSmGrid.CommitEdit(DataGridViewDataErrorContexts.Commit);
}

private void LocalSmGrid_CellValueChanged(object sender, DataGridViewCellEventArgs e)
{
MessageBox.Show("Yay!");
}

# re: How to get a CheckBox in a Winforms DataGridView to react to the first click

Left by SanderEvers at 3/9/2010 5:05 AM
Gravatar This is the original idea, but also works for more columns and works in general. (You would even be able to use it in a inherent class of the DataGridView)

Private Sub DG_InkoopRegels_CellMouseUp(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DataGridViewCellMouseEventArgs) Handles DG_InkoopRegels.CellMouseUp
If TypeOf DG_InkoopRegels.Columns(e.ColumnIndex) Is DataGridViewCheckBoxColumn AndAlso e.RowIndex > -1 Then
DG_InkoopRegels.EndEdit()
End If
End Sub

# re: How to get a CheckBox in a Winforms DataGridView to react to the first click

Left by phenevo at 4/2/2010 8:26 AM
Gravatar Hi, could you look at : http://stackoverflow.com/questions/2565875/locked-datagridview-linq-is-a-problem

I have problem with your solution.

# re: How to get a CheckBox in a Winforms DataGridView to react to the first click

Left by Jim at 5/11/2010 9:45 PM
Gravatar Saved me a bunch of time. Thanks!

# re: How to get a CheckBox in a Winforms DataGridView to react to the first click

Left by Ted at 9/28/2011 10:49 PM
Gravatar You will also need to hookup the KeyUp

# re: How to get a CheckBox in a Winforms DataGridView to react to the first click

Left by Muthu at 4/30/2012 12:53 AM
Gravatar Thanks lot!!! You saved lot of my time

# re: How to get a CheckBox in a Winforms DataGridView to react to the first click

Left by Poosnik at 5/18/2012 9:51 PM
Gravatar It worked Thanks

# re: How to get a CheckBox in a Winforms DataGridView to react to the first click

Left by Pablo at 4/12/2017 3:03 AM
Gravatar I have a problem with this process, i can change the datagridrow if checkbox is chequed but not in the same time!, only when i click on the other checkbox
My code here:

Private Sub grid_CHECK_LIST_ORACLE_CurrentCellDirtyStateChanged(sender As Object, e As EventArgs) Handles grid_CHECK_LIST_ORACLE.CurrentCellDirtyStateChanged
If grid_CHECK_LIST_ORACLE.IsCurrentCellDirty Then
grid_CHECK_LIST_ORACLE.CommitEdit(DataGridViewDataErrorContexts.Commit)
End If
End Sub

Private Sub grid_CHECK_LIST_ORACLE_CellContentClick(sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles grid_CHECK_LIST_ORACLE.CellContentClick
If e.ColumnIndex = 0 AndAlso Not grid_CHECK_LIST_ORACLE.Rows(e.RowIndex).IsNewRow Then
grid_CHECK_LIST_ORACLE.EndEdit()
End If

If e.ColumnIndex = 0 And e.RowIndex > -1 Then
If grid_CHECK_LIST_ORACLE.Rows(e.RowIndex).Cells("checkBoxColumn").Value = True Then

Dim isChecked As Boolean = DirectCast(grid_CHECK_LIST_ORACLE(e.ColumnIndex, e.RowIndex).FormattedValue, [Boolean])
If isChecked Then
grid_CHECK_LIST_ORACLE.Rows(e.RowIndex).DefaultCellStyle.BackColor = Color.LightSeaGreen
grid_CHECK_LIST_ORACLE.Rows(e.RowIndex).DefaultCellStyle.ForeColor = Color.White
End If
Else
grid_CHECK_LIST_ORACLE.Rows(e.RowIndex).DefaultCellStyle.BackColor = Color.White
grid_CHECK_LIST_ORACLE.Rows(e.RowIndex).DefaultCellStyle.ForeColor = Color.Black
End If
End If

End Sub

please help!

# re: How to get a CheckBox in a Winforms DataGridView to react to the first click

Left by Michelle at 5/26/2017 11:30 AM
Gravatar Here is solution:

http://www.codingeverything.com/2013/01/firing-datagridview-cellvaluechanged.html

Your comment:





 

Copyright © Changhong Fu

Design by Bartosz Brzezinski

Design by Phil Haack Based On A Design By Bartosz Brzezinski