将DGV列升序排序,同时将空值放在底部

时间:2017-05-30 20:37:27

标签: vb.net

我需要这样做,以便列中的空值放在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)

不要担心为什么我的高度为空值,我只是使用示例数据来解决这个问题。

2 个答案:

答案 0 :(得分:3)

字符串排序

您可以通过为DataGridViewMSDN'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))

它有效!

DataGridView sort example

数字排序

前面的示例显示了基于字符串的排序算法。它将根据字符集在字符集中的第一个字符逐个字符地对每个单元格进行排序。

如果您想要以数字方式对行进行排序,则必须对代码进行更多调整:

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