Search code examples
c#.netvb.netwinformsdatagridviewcomboboxcell

Simulating OnClick event for DataGridViewCheckBox?


VB or C#... A trivial task at the first sight. For DataGridViewCheckBox, create OnClick() method which is called if and only if value of checkbox was changed by user (using Space or left mouse click).

Perhaps there aleady is such an event – CellContentClick – but it seems to suffer from bug related to order of events and changing value by Space does not work due to call to EndEdit().

                   → view C# equivalents

Private Sub DataGridView1_CellContentClick(sender As Object, e As DataGridViewCellEventArgs) _
        Handles DataGridView1.CellContentClick
    If IsCurrentCellCheckBoxCell(sender) Then
        DirectCast(sender, DataGridView).EndEdit()
        PrintValueOfCurrentCheckBox()
    End If
End Sub

Are we able to simulate event which works seamlessly, without bugs?

Consistency criteria:

(just a standard UX – they should be obvious)

  • Change event should be fired when clicked inside the checkbox or after pressing Space.

  • Change event should not be fired when clicked inside chackbox cell, but outside the checkbox.

  • Change event should be fired only when value changes (true ←→ false).

  • Testing for checkbox value should give result corresponding to checkbox state.

Helper code:

'result validation
Sub PrintValueOfCurrentCheckBox()
    If DataGridView1.CurrentCell Is Nothing Then Return
    Console.WriteLine(DataGridView1.CurrentRow.Cells(DataGridView1.CurrentCell.ColumnIndex).Value.ToString())
End Sub

'universal helper
Shared Function IsCurrentCellCheckBoxCell(dataGridViewSender As Object) As Boolean
    If TypeOf dataGridViewSender Is DataGridView Then
        With DirectCast(dataGridViewSender, DataGridView)
            If .CurrentCell IsNot Nothing Then
                Dim currentColumn As DataGridViewColumn = .Columns(.CurrentCell.ColumnIndex)
                Return TypeOf currentColumn Is DataGridViewCheckBoxColumn
            End If
        End With
    End If
    Return False
End Function

(C# or VB – whatever you prefer.)


Solution

  • Call to EndEdit() needs balacing – add BeginEdit().

    I found the culprit. Switching check box using Space key did not work because EndEdit() isn't enough. It needs to be balanced by BeginEdit().

    Private Sub DataGridView1_CellContentClick(sender As Object, e As DataGridViewCellEventArgs) _
            Handles DataGridView1.CellContentClick
        If IsCurrentCellCheckBoxCell(sender) Then
            DirectCast(sender, DataGridView).EndEdit()
            PrintValueOfCurrentCheckBox()
            DirectCast(sender, DataGridView).BeginEdit(false) ' added method call
        End If
    End Sub
    

    Now, detection of change of the check box and and reading of its immediate state seem to be reliable.