Thursday, March 14, 2013

Using IComparable to sort a list

     I had a list of objects that I used to attach to a datagridview to display. I wanted to be able to sort by clicking on the header field, but this list did not use the BindingList interface, so the datagridview mechanisms would not do the sorting for me. So I looked around and decided I would re-sort the array and then reattach it to the datagridview manually to get the sorts I wanted.
  I found a number of examples of how to do this on the web, but I ran into errors when I tried to implement it. I found that my definition of the list was causing the problem

I had defined my list as:

  dim myLogLines as List(Of LogLinesClass)

When I redefined mylogline to this, everything started working with the IComparable sort routines:

dim myLogLines as ArrayList

So I changed from a List(Of LogLinesClass) to just an ArrayList.



   [Code]

Imports System.Text.RegularExpressions
Imports System.Collections

Public Class LogFileClass
    Implements IComparable

    Dim sRegExp As String
    Dim myReCol As List(Of Regex) = New List(Of Regex)

    Dim myRegEx As Regex

    Function CompareTo(ByVal obj As Object) As Integer Implements IComparable.CompareTo
        Dim c As LogFileClass = CType(obj, LogFileClass)

        Return String.Compare(Me.Program, c.Program)
    End Function

    Private Class sortUserAscendingHelper : Implements IComparer
        Function Compare(ByVal a As Object, ByVal b As Object) As Integer Implements IComparer.Compare
            Dim c1 As LogFileClass = CType(a, LogFileClass)
            Dim c2 As LogFileClass = CType(b, LogFileClass)

            'Dim result As Integer
            'result = String.Compare(c1.Program, c2.Program)

            'Return result

            If (c1.User > c2.User) Then
                Return 1
            End If

            If (c1.User < c2.User) Then
                Return -1
            Else
                Return 0
            End If
        End Function
    End Class

    Private Class sortUserDescendingHelper : Implements IComparer
        Function Compare(ByVal a As Object, ByVal b As Object) As Integer Implements IComparer.Compare
            Dim c1 As LogFileClass = CType(a, LogFileClass)
            Dim c2 As LogFileClass = CType(b, LogFileClass)

            'Dim result As Integer

            'result = String.Compare(c2.Program, c1.Program)

            'Return result

            If (c1.User < c2.User) Then
                Return 1
            End If

            If (c1.User > c2.User) Then
                Return -1
            Else
                Return 0
            End If
        End Function
    End Class

    Private Class sortProgramDescendingHelper : Implements IComparer
        Function Compare(ByVal a As Object, ByVal b As Object) As Integer Implements IComparer.Compare
            Dim c1 As LogFileClass = CType(a, LogFileClass)
            Dim c2 As LogFileClass = CType(b, LogFileClass)
            'Return String.Compare(c2.Program, c1.Program)

            If (c1.Program < c2.Program) Then
                Return 1
            End If

            If (c1.Program > c2.Program) Then
                Return -1
            Else
                Return 0
            End If
        End Function
    End Class
    Private Class sortElapsedAscendingHelper : Implements IComparer
        Function Compare(ByVal a As Object, ByVal b As Object) As Integer Implements IComparer.Compare
            Dim c1 As LogFileClass = CType(a, LogFileClass)
            Dim c2 As LogFileClass = CType(b, LogFileClass)

            'Dim result As Integer
            'result = String.Compare(c1.Program, c2.Program)

            'Return result

            If (c1.Elapsed > c2.Elapsed) Then
                Return 1
            End If

            If (c1.Elapsed < c2.Elapsed) Then
                Return -1
            Else
                Return 0
            End If
        End Function
    End Class

    Private Class sortElapsedDescendingHelper : Implements IComparer
        Function Compare(ByVal a As Object, ByVal b As Object) As Integer Implements IComparer.Compare
            Dim c1 As LogFileClass = CType(a, LogFileClass)
            Dim c2 As LogFileClass = CType(b, LogFileClass)

            'Dim result As Integer
            'result = String.Compare(c1.Program, c2.Program)

            'Return result

            If (c1.Elapsed > c2.Elapsed) Then
                Return -1
            End If

            If (c1.Elapsed < c2.Elapsed) Then
                Return 1
            Else
                Return 0
            End If
        End Function
    End Class

    Public Shared Function sortUserAscending() As IComparer
        Return CType(New sortUserAscendingHelper(), IComparer)
    End Function

    Public Shared Function sortUserDescending() As IComparer
        Return CType(New sortUserDescendingHelper(), IComparer)
    End Function

    Public Shared Function sortProgramDescending() As IComparer
        Return CType(New sortProgramDescendingHelper(), IComparer)
    End Function
    Public Shared Function sortElapsedAscending() As IComparer
        Return CType(New sortElapsedAscendingHelper(), IComparer)
    End Function
    Public Shared Function sortElapsedDescending() As IComparer
        Return CType(New sortElapsedDescendingHelper(), IComparer)
    End Function
[/CODE]


code to call and sort the arraylist
[CODE]
   Private Sub SortDGV(ByVal vFieldName As String, ByVal vSortOrder As ListSortDirection)
        If vFieldName.ToLower = "user" Then
            If vSortOrder = ListSortDirection.Ascending Then
                myLogLines.Sort(LogFileClass.sortUserAscending)
            Else
                myLogLines.Sort(LogFileClass.sortUserDescending)
            End If
        ElseIf vFieldName.ToLower = "program" Then
            If vSortOrder = ListSortDirection.Ascending Then
                myLogLines.Sort()
            Else
                myLogLines.Sort(LogFileClass.sortProgramDescending)
            End If
        ElseIf vFieldName.ToLower = "elapsed" Then
            If vSortOrder = ListSortDirection.Ascending Then
                myLogLines.Sort(LogFileClass.sortElapsedAscending)
            Else
                myLogLines.Sort(LogFileClass.sortElapsedDescending)
            End If
        Else
            If vSortOrder = ListSortDirection.Ascending Then
                myLogLines.Sort(New SimpleComparer(vFieldName, SortOrder.Ascending))
            Else
                myLogLines.Sort(New SimpleComparer(vFieldName, SortOrder.Descending))
            End If
        End If

        dgvLogLines.DataSource = myLogLines
        dgvLogLines.Refresh()
    End Sub
[/CODE]


No comments:

Post a Comment