Home All Groups Group Topic Archive Search About

Sort on two columns in ListView?

Author
12 Oct 2006 11:56 PM
vb newbie
Does anybody have suggestions on how to programatically sort a ListView
on TWO subitem columns?
Here's the code I'm using to sort on one subitem:

Public Function Compare(ByVal x As Object, ByVal y As _
        Object) As Integer Implements _
        System.Collections.IComparer.Compare
        Dim item_x As ListViewItem = DirectCast(x, _
            ListViewItem)
        Dim item_y As ListViewItem = DirectCast(y, _
            ListViewItem)

        ' Get the sub-item values.
        Dim string_x As String
        If item_x.SubItems.Count <= m_ColumnNumber Then
            string_x = ""
        Else
            string_x = item_x.SubItems(m_ColumnNumber).Text
        End If

        Dim string_y As String
        If item_y.SubItems.Count <= m_ColumnNumber Then
            string_y = ""
        Else
            string_y = item_y.SubItems(m_ColumnNumber).Text
        End If

        ' Compare them based on column types
        Select Case (Form1.sortTypes(m_ColumnNumber))
            Case "c"
                If m_SortOrder = SortOrder.Ascending Then
                    Return String.Compare(string_x, string_y)
                Else
                    Return String.Compare(string_y, string_x)
                End If
            Case "d"
                If m_SortOrder = SortOrder.Ascending Then
                    Return Date.Compare(string_x, string_y)
                Else
                    Return Date.Compare(string_y, string_x)
                End If
            Case "n"
                If m_SortOrder = SortOrder.Ascending Then
                    Return Decimal.Compare(string_x, string_y)
                Else
                    Return Decimal.Compare(string_y, string_x)
                End If

        End Select
    End Function

Author
13 Oct 2006 1:46 AM
teslar91
Yep.

I didn't test in VB itself, but I'm pretty sure this transformation of
your code does what you want.

Assume m_ColumnNumber is now an array (to hold multiple column
numbers).  And there's another variable, NumOfSortColumns, to tell the
Compare routine how many columns it's working with.

Public Function Compare(ByVal x As Object, ByVal y As _
        Object) As Integer Implements _
        System.Collections.IComparer.Compare
        Dim item_x As ListViewItem = DirectCast(x, _
            ListViewItem)
        Dim item_y As ListViewItem = DirectCast(y, _
            ListViewItem)
        Dim string_x, string_y As String
    Dim SortColumn As Integer
        Dim ColumnNumber As Integer
        Dim Result As Integer

        For SortColumn = 0 to NumOfSortColumns-1
          ColumnNumber = m_ColumnNumber(SortColumn)

          ' Get the sub-item values.
          If item_x.SubItems.Count <= ColumnNumber Then
              string_x = ""
          Else
              string_x = item_x.SubItems(ColumnNumber).Text
          End If
          If item_y.SubItems.Count <= ColumnNumber Then
              string_y = ""
          Else
              string_y = item_y.SubItems(ColumnNumber).Text
          End If

          ' Compare them based on column types.
          Select Case (Form1.sortTypes(ColumnNumber))
              Case "c": Result = String.Compare(string_x, string_y)
              Case "d": Result = Date.Compare(string_x, string_y)
              Case "n": Result = Decimal.Compare(string_x, string_y)
          End Select

          ' Reverse the sign on the sort result if sorting descending.
          If m_SortOrder = SortOrder.Descending Then Result *= -1

          ' Set the return value to the result.
          ' If result is non-zero (not equal), exit immediately.
          ' But if result is zero (equal), compare the next sort column
(if available).
          Compare = Result
          If Result <> 0 Then Exit Function

        Next

    End Function