I am trying to sort a DataGridView control by a column that contains DBNull values. This DataGridView control is bound to an SQL Server 2012 Database.
When I click the headercell (to sort in ascending order), the DBNull values are sorted ahead of the rest of the integer values, so that the top rows in the column are all blank, and then after that the integer values 1,2,3 etc are in ascending order.
How do I get around this? I would rather the DataGridView control sort the rows with values at the top, followed by the DBNulls.
I have tried to insert a higher value into the blank cells, which then sorts them correctly, but when I return those values back to System.DBNull.value, the sort order reverts back to the way above.
My code is as follows:
If dgv.Columns(e.ColumnIndex).Name.EndsWith("Position") Then
intSortingRunningPosition = 1000
dgv.Sort(baseColumn, System.ComponentModel.ListSortDirection.Ascending)
newColumn.HeaderCell.SortGlyphDirection = Windows.Forms.SortOrder.Ascending
For Each dr As DataGridViewRow In dgv.Rows
If dr.Cells(e.ColumnIndex).Value Is System.DBNull.Value Then
dr.Cells(e.ColumnIndex).Value = intSortingRunningPosition
intSortingRunningPosition += 1
End If
Next
dgv.Sort(newColumn, System.ComponentModel.ListSortDirection.Ascending)
For Each dr As DataGridViewRow In dgv.Rows
If dr.Cells(e.ColumnIndex).Value >= 1000 Then
dr.Cells(e.ColumnIndex).Value = System.DBNull.Value
End If
Next
End If
Sorry if this is confusing. Thanks!
Update:
I have modified my code to work with the IComparer method, and have come up with the following:
Public Function Compare(ByVal x As Object, ByVal y As Object) As Integer _
Implements System.Collections.IComparer.Compare
Dim DataGridViewRow1 As DataGridViewRow = CType(x, DataGridViewRow)
Dim DataGridViewRow2 As DataGridViewRow = CType(y, DataGridViewRow)
Dim CompareResult As Integer
Dim intDGV1Cell0Value As Integer = Nothing
Dim intDGV1Cell1Value As Integer = Nothing
Dim intDGV2Cell0Value As Integer = Nothing
Dim intDGV2Cell1Value As Integer = Nothing
Try
intDGV1Cell0Value = CInt(DataGridViewRow1.Cells(0).Value)
Catch ex As Exception
intDGV1Cell0Value = Int32.MaxValue
End Try
Try
intDGV1Cell1Value = CInt(DataGridViewRow1.Cells(1).Value)
Catch ex As Exception
intDGV1Cell1Value = Int32.MaxValue
End Try
Try
intDGV2Cell0Value = CInt(DataGridViewRow2.Cells(0).Value)
Catch ex As Exception
intDGV2Cell0Value = Int32.MaxValue
End Try
Try
intDGV2Cell1Value = CInt(DataGridViewRow2.Cells(1).Value)
Catch ex As Exception
intDGV2Cell1Value = Int32.MaxValue
End Try
' Try to sort based on the Last Name column.
CompareResult = System.String.Compare(intDGV1Cell1Value, intDGV2Cell1Value)
' If the Last Names are equal, sort based on the First Name.
If CompareResult = 0 Then
CompareResult = System.String.Compare(intDGV1Cell0Value, intDGV2Cell0Value)
End If
Return CompareResult * sortOrderModifier
End Function
The null value is now not sorting at all. Any ideas on what I am doing wrong here? I am sure I am a bit out of the ballpark as it is…
I was fairly unsucessful using the Sort(ICompare) method to sort this database because it was bound to an external dataset. I ended up modifying my connection string and refilling the datatable.
My code is as follows:
I call this subroutine on the header cell click event. I send the Column name, sort direction, and datatype to this subroutine.
This code also allows me to sort the column depending on the type of data. If there are alphanumeric strings, I can sort them in a similar order as if they were only integers. The DBNull values are always placed at the end of the sort.
Thanks for the help!