🛠️ VB.NET WinForms: Fixing Multiple Triggers of DataGridView.CellValueChanged with CheckBox Column
DataGridView.CellValueChanged fires more than once – How to handle it
Have you ever added a checkbox column to a DataGridView in VB.NET WinForms and found that clicking it triggers the CellValueChanged event multiple times? This can lead to all sorts of headaches, like your code running repeatedly or your UI acting glitchy. Don’t worry—this tutorial will show you a simple fix to make your checkboxes behave!
This issue can cause:
- Redundant logic execution, making your app do the same thing over and over.
- Glitchy UI behavior, like buttons enabling or disabling unexpectedly.
- Performance overhead, slowing down your application.
We’ll walk you through a reliable solution using CurrentCellDirtyStateChanged and CellValueChanged to ensure your code runs exactly once per checkbox toggle.
⚠️ The Problem
When you click a checkbox in a DataGridView, the checkbox state doesn’t update immediately. Instead, it’s marked as “dirty” (changed but not saved), and the CellValueChanged event can fire before the change is finalized, sometimes multiple times. This is because the control waits for the cell to lose focus before committing the change, which can lead to unexpected behavior.
✅ The Solution: Commit the Change First
To fix this, you need to commit the checkbox change immediately when it’s toggled. You can do this by using two events together:
CurrentCellDirtyStateChanged– Detects when the checkbox is toggled and commits the change.CellValueChanged– Handles your logic after the change is committed.
🔧 VB.NET Code Implementation
1. CellValueChanged – Main Handler
This event handles the logic after the checkbox value is committed. The example below ensures only one checkbox is checked at a time (like radio buttons) and updates UI elements accordingly.
Private Sub DatagridView1_CellValueChanged(sender As Object, e As DataGridViewCellEventArgs)
If TypeOf DatagridView1.CurrentCell Is DataGridViewCheckBoxCell Then
Dim ChkCnt As Integer
Dim columnIndex As Integer = OptCol.Index
If e.ColumnIndex = columnIndex Then
Dim isChecked As Boolean = CBool(DatagridView1.Rows(e.RowIndex).Cells(e.ColumnIndex).Value)
RemoveHandler DatagridView1.CellValueChanged, AddressOf DatagridView1_CellValueChanged
If isChecked Then
For Each row As DataGridViewRow In DatagridView1.Rows
If row.Index <> e.RowIndex Then
row.Cells(columnIndex).Value = Not isChecked
ChkCnt -= 1
Else
ChkCnt += 1
End If
Next
End If
If ChkCnt < 0 Then
TileBarItem1.Enabled = False
TileBarItem2.Enabled = True
TileBarItem3.Enabled = True
ElseIf ChkCnt = 0 Then
TileBarItem1.Enabled = True
TileBarItem2.Enabled = False
TileBarItem3.Enabled = False
End If
Debug.WriteLine(String.Format("{0} count", ChkCnt.ToString))
End If
End If
End Sub2. CurrentCellDirtyStateChanged – Commit the Change First
This event commits the checkbox change immediately, ensuring CellValueChanged fires only once with the correct value.
Private Sub DatagridView1_CurrentCellDirtyStateChanged(sender As Object, e As EventArgs)
If TypeOf DatagridView1.CurrentCell Is DataGridViewCheckBoxCell Then
If DatagridView1.IsCurrentCellDirty Then
DatagridView1.CommitEdit(DataGridViewDataErrorContexts.Commit)
AddHandler DatagridView1.CellValueChanged, AddressOf DatagridView1_CellValueChanged
End If
End If
End Sub
💡 Why This Fix Works
Checkboxes in a DataGridView don’t update their value until the edit is committed, which typically happens when the cell loses focus. This delay can cause CellValueChanged to fire multiple times or with incorrect values.
By using CurrentCellDirtyStateChanged to call CommitEdit(), you force the checkbox value to update immediately, ensuring CellValueChanged fires only once with the correct state.
💬 Pro Tips for Developers
To make your VB.NET WinForms application robust when using checkbox columns, keep these tips in mind:
- Always use this pattern to avoid multiple event triggers, especially if your app enables or disables features based on checkbox states.
- Test your logic with different row counts, as the example’s counter (
ChkCnt) may behave unexpectedly with negative values. - Consider setting up event handlers once during form initialization to avoid unnecessary
AddHandler/RemoveHandlercalls.
🔗 Read More
This fix was tested and documented on our tutorial blog:
👉 VB.NET WinForms DataGridView.CellValueChanged fires multiple times (Solved)
♥ Here are some online Visual Basic lessons and courses:

No comments:
Post a Comment