我需要这样做,以便列中的空值放在DGV列的底部。我需要按升序排序,这会先将空值放入,但我不想先看到它,我想在最大值之后看到它们。这是我到目前为止,但它首先放置null值,我不知道如何处理将null值放在最后的自定义排序。例如:
dim display as integer = 0
dataGridView1.Columns("Weight").DisplayIndex = display
display += 1
dataGridView1.Columns("Height").DisplayIndex = display
dataGridView1.Sort(dataGridView1.Columns("Height"), System.ComponentModel.ListSortDirection.Ascending)
不要担心为什么我的高度为空值,我只是使用示例数据来解决这个问题。
答案 0 :(得分:3)
您可以通过为DataGridView
(MSDN's code的改编版本)创建自定义行比较器来完成您的要求:
Public Class DataGridViewColumnComparer
Implements IComparer
Private SortOrderModifier As Integer = 1
Private ColumnName As String
Public Sub New(ByVal ColumnName As String, ByVal Order As SortOrder)
Me.ColumnName = ColumnName
If Order = SortOrder.Descending Then
SortOrderModifier = -1
ElseIf Order = SortOrder.Ascending Then
SortOrderModifier = 1
End If
End Sub
Public Function Compare(ByVal x As Object, ByVal y As Object) As Integer Implements IComparer.Compare
Dim Row1 As DataGridViewRow = CType(x, DataGridViewRow)
Dim Row2 As DataGridViewRow = CType(y, DataGridViewRow)
Dim Row1Value As String = Row1.Cells(ColumnName).Value.ToString()
Dim Row2Value As String = Row2.Cells(ColumnName).Value.ToString()
'If CompareResult = 1 that means that Row1 should be placed BELOW Row2.
'If CompareResult = -1 that means that Row1 should be placed ABOVE Row2.
Dim CompareResult As Integer = String.Compare(Row1Value, Row2Value)
If String.IsNullOrEmpty(Row1Value) = True Then
CompareResult = 1 'Row1 has an empty/null value, place it below Row2.
ElseIf String.IsNullOrEmpty(Row2Value) = True Then
CompareResult = -1 'Row2 has an empty/null value, place Row1 above.
End If
Return CompareResult * SortOrderModifier
End Function
End Class
<强>用法:强>
DataGridView1.Sort(New DataGridViewColumnComparer("Height", SortOrder.Ascending))
它有效!
前面的示例显示了基于字符串的排序算法。它将根据字符集在字符集中的第一个字符逐个字符地对每个单元格进行排序。
如果您想要以数字方式对行进行排序,则必须对代码进行更多调整:
Public Class DataGridViewNumericComparer
Implements IComparer
Private SortOrderModifier As Integer = 1
Private ColumnName As String
Public Sub New(ByVal ColumnName As String, ByVal Order As SortOrder)
Me.ColumnName = ColumnName
If Order = SortOrder.Descending Then
SortOrderModifier = -1
ElseIf Order = SortOrder.Ascending Then
SortOrderModifier = 1
End If
End Sub
Public Function Compare(ByVal x As Object, ByVal y As Object) As Integer Implements IComparer.Compare
Dim Row1 As DataGridViewRow = CType(x, DataGridViewRow)
Dim Row2 As DataGridViewRow = CType(y, DataGridViewRow)
Dim Row1Value As String = Row1.Cells(ColumnName).Value.ToString()
Dim Row2Value As String = Row2.Cells(ColumnName).Value.ToString()
Dim Row1NumVal As Nullable(Of Long) = Nothing
Dim Row2NumVal As Nullable(Of Long) = Nothing
Dim Row1Temp As Long = 0
Dim Row2Temp As Long = 0
If Long.TryParse(Row1Value, Row1Temp) = True Then Row1NumVal = Row1Temp
If Long.TryParse(Row2Value, Row2Temp) = True Then Row2NumVal = Row2Temp
'If CompareResult = 1 that means that Row1 should be placed BELOW Row2.
'If CompareResult = -1 that means that Row1 should be placed ABOVE Row2.
Dim CompareResult As Integer
If Row1NumVal.HasValue = True AndAlso Row2NumVal.HasValue = True Then
CompareResult = Row1NumVal.Value.CompareTo(Row2NumVal.Value)
ElseIf Row1NumVal.HasValue = False Then
CompareResult = 1
ElseIf Row2NumVal.HasValue = False Then
CompareResult = -1
End If
Return CompareResult * SortOrderModifier
End Function
End Class
<强>用法:强>
DataGridView1.Sort(New DataGridViewNumericComparer("Height", SortOrder.Ascending))
此版本将按数字顺序对所有数字进行排序,并将不是数字的所有数字放在底部。
答案 1 :(得分:1)
另一种选择可能是处理DataGridView.SortCompare
事件:
Private Sub DataGridView1_SortCompare(sender As Object, e As DataGridViewSortCompareEventArgs) Handles DataGridView1.SortCompare
If e.CellValue1 Is Nothing Then e.SortResult += 1 : e.Handled = True
If e.CellValue2 Is Nothing Then e.SortResult -= 1 : e.Handled = True
If e.Column.DataGridView.SortOrder = SortOrder.Descending Then e.SortResult = -e.SortResult
End Sub