I've got a DataGridView control in a Windows forms application. There are four columns with string data and three with DateTime data. I'm adding the rows programmatically using the Rows.Add() method. All of the columns have SortMode set to Automatic. Clicking the column headers to sort just works, except for the one DateTime column that has some nulls. When the user clicks that column's header, it throws an ArgumentException: Object must be of type DateTime.
I know the hard way to get around this: setting all of the SortModes to NotSortable, handling the ColumnHeaderMouseClick event and sorting the whole thing manually. I'm looking for the easy way.
Is there a property or something I can set, or some other relatively simple way to allow this column to sort with nulls in it?
An easy solution is to add a "tonull" function, which you run the e.cellvalue1 and 2 through each time a comparison is made. If the value is "" then the value of the cell will be changed to 01/01/1001 if you want null values to appear first on the sort or 01/01/3001 or something ridiculously high if you want them to appear last on the sort.
Private Sub dgvTable_SortCompare(ByVal sender As Object, ByVal e As DataGridViewSortCompareEventArgs) Handles dgvTable.SortCompare
If e.Column.Index = 4 Then
e.SortResult = System.DateTime.Compare(todatenull(e.CellValue1), todatenull(e.CellValue2))
End If
e.Handled = True
End Sub
Function todatenull(ByVal cellvalue)
If cellvalue = "" Then
Return "01/01/1001"
Else
Return cellvalue
End If
End Function
Here's the solution I came up with. The DataGridView raises a SortCompare event that you can use to input custom sorting. I'm handling that event and making null values sort out higher than non-null values (you could just as easily make nulls lower than non-nulls). Here's the VB code. I'm assuming every cell value is IComparable (if not it will be handled by the normal error handling logic.)
Try
If e.CellValue1 Is Nothing OrElse e.CellValue1.Equals(DBNull.Value) Then
If e.CellValue2 Is Nothing OrElse e.CellValue2.Equals(DBNull.Value) Then
e.SortResult = 0
Else
e.SortResult = 1
End If
Else
If e.CellValue2 Is Nothing OrElse e.CellValue2.Equals(DBNull.Value) Then
e.SortResult = -1
Else
e.SortResult = DirectCast(e.CellValue1, IComparable).CompareTo(DirectCast(e.CellValue2, IComparable))
End If
End If
e.Handled = True
Catch ex As Exception
HandleError("Error sorting result grid values", ex)
Close()
End Try
If anybody has any improvements on this please feel free to post them.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With