Search code examples
vb.netdatagridviewdatagridviewcheckboxcell

How can I sort a WinForms DataGridView on a CheckBox column?


So I had a DataGridView with autogenerated columns, some of which were checkbox columns. When I clicked on the check box column's header, it didn't sort. I researched it and it turns out that Microsoft didn't include automatic sorting for checkbox columns... Which I think is absurd--how hard is it to sort checked / not checked?

How can you get a DataGridView to sort check box columns for you?

Here's what I came up with:


Solution

  • First you need to hook into two events, the column added event and the column header click event:

    AddHandler dg.ColumnAdded, AddressOf dgColumnAdded
    AddHandler dg.ColumnHeaderMouseClick, AddressOf dgSortColumns
    

    Then, enable programmatic sorting for each check box column:

    Private Sub dgColumnAdded(ByVal sender As Object, _
    ByVal e As System.Windows.Forms.DataGridViewColumnEventArgs)
        If e.Column.GetType Is GetType(DataGridViewCheckBoxColumn) Then
            e.Column.SortMode = DataGridViewColumnSortMode.Programmatic
        End If
    End Sub
    

    Then, create a handler that will sort a checkbox column, but do nothing for columns that will handle their own sorting:

    Private Sub dgSortColumns(ByVal sender As Object, _
    ByVal e As System.Windows.Forms.DataGridViewCellMouseEventArgs)
        Dim dg As DataGridView = sender
        Dim c As DataGridViewColumn = dg.Columns(e.ColumnIndex)
        If c.SortMode = DataGridViewColumnSortMode.Programmatic Then
            If dg.SortedColumn IsNot Nothing _
            AndAlso dg.SortedColumn.Name <> c.Name Then
                dg.Sort(c, System.ComponentModel.ListSortDirection.Ascending)
            Else
                Select Case dg.SortOrder
                    Case Windows.Forms.SortOrder.None
                        dg.Sort(c, System.ComponentModel.ListSortDirection.Ascending)
                    Case Windows.Forms.SortOrder.Ascending
                        dg.Sort(c, System.ComponentModel.ListSortDirection.Descending)
                    Case Windows.Forms.SortOrder.Descending
                        dg.Sort(c, System.ComponentModel.ListSortDirection.Ascending)
                End Select
            End If
        End If
    End Sub
    

    And there you go! Now was it really that hard, Microsoft? ;-)