Welcome to ADO.NET Access 2003—your ultimate hub for VB.NET and ADO.NET programming excellence. Discover in-depth tutorials, practical code samples, and expert troubleshooting guides covering a broad range of topics—from building robust WinForms applications and seamless MS Access integration to working with SQL Server, MySQL, and advanced tools like WebView2 and Crystal Reports. Whether you're a beginner or a seasoned developer, our step-by-step articles are designed to empower you to optimize.

Looking for MS Access Developer❓❓

Application developer

Post Page Advertisement [Top]

🛠️ VB.NET WinForms: Fixing Multiple Triggers of DataGridView.CellValueChanged with CheckBox Column

DataGridView CheckBox Issue Screenshot

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:

  1. CurrentCellDirtyStateChanged – Detects when the checkbox is toggled and commits the change.
  2. 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:

Bottom Ad [Post Page]