🛠️ 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 Sub
2. 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
/RemoveHandler
calls.
🔗 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