none
The IComparer for date sorting RRS feed

  • Question

  • The code below is for sorting date column, the first clicking is right, but the second clicking is not right, why?

    Public Class Form1
        Private Sub ColumnHeader1_Click(sender As Object, e As EventArgs) Handles ColumnHeader1.Click
            Static oSorter As New AdvTreeSorter
            ColumnHeader1.SortComparer = oSorter
            ColumnHeader1.Sort()
        End Sub
    End Class

    Public Class AdvTreeSorter

        Implements Collections.IComparer
        Protected m_oCulture As Globalization.CultureInfo = Globalization.CultureInfo.CurrentCulture

        Private Function Compare(ByVal o1 As Object, ByVal o2 As Object) As Integer Implements Collections.IComparer.Compare
            Dim node1 As Node = o1
            Dim node2 As Node = o2
            Dim sTxt1 As String = node1.Text
            Dim sTxt2 As String = node2.Text

            Dim dDate1 As Date = Date.Parse(sTxt1, m_oCulture.DateTimeFormat)
            Dim dDate2 As Date = Date.Parse(sTxt2, m_oCulture.DateTimeFormat)

            Return Date.Compare(dDate1, dDate2)
        End Function
    End Class

    1. Init 

    2. First clicking

    3. Second clicking

    Saturday, February 22, 2020 11:07 PM

Answers

  • Hi,
    without knowing your whole code is impossible to find a problem . My demo works fine:

    Public Class Form81
    
      Private WithEvents lv As New ListView With {.Dock = DockStyle.Fill, .View = View.Details}
      Private columnSorter As New AdvTreeSorter
    
      Private Sub Form81_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        lv.ListViewItemSorter = columnSorter
        Me.Controls.Add(lv)
        lv.Columns.Add("Column")
    
        lv.Items.Add(New ListViewItem("2019/5/25"))
        lv.Items.Add(New ListViewItem("2019/12/25"))
        lv.Items.Add(New ListViewItem("2019/1/25"))
        lv.Items.Add(New ListViewItem("2019/11/25"))
        lv.Items.Add(New ListViewItem("2019/10/15"))
        lv.Items.Add(New ListViewItem("2019/1/30"))
      End Sub
    
    
      Private Sub ColumnHeader1_Click(sender As Object, e As EventArgs) Handles lv.ColumnClick
        If columnSorter.Order = SortOrder.Ascending Then
          columnSorter.Order = SortOrder.Descending
        Else
          columnSorter.Order = SortOrder.Ascending
        End If
        lv.Sort()
      End Sub
    
      Public Class AdvTreeSorter
    
        Implements Collections.IComparer
        Protected m_oCulture As Globalization.CultureInfo = Globalization.CultureInfo.CurrentCulture
    
        Private Function Compare(ByVal o1 As Object, ByVal o2 As Object) As Integer Implements Collections.IComparer.Compare
          If Order = SortOrder.None Then Return 0
    
          Dim sTxt1 = CType(o1, ListViewItem).Text
          Dim sTxt2 = CType(o2, ListViewItem).Text
    
          Dim dDate1 As Date = Date.Parse(sTxt1, m_oCulture.DateTimeFormat)
          Dim dDate2 As Date = Date.Parse(sTxt2, m_oCulture.DateTimeFormat)
    
          Return If(Order = SortOrder.Ascending, Date.Compare(dDate1, dDate2), -Date.Compare(dDate1, dDate2))
        End Function
    
        Public Property Order As SortOrder
    
      End Class
    
    End Class


    --
    Best Regards / Viele Grüße
    Peter Fleischer (former MVP for Developer Technologies)
    Homepage, Tipps, Tricks


    • Edited by Peter Fleischer Sunday, February 23, 2020 1:34 PM
    • Marked as answer by gaxjyxq Sunday, February 23, 2020 10:51 PM
    Sunday, February 23, 2020 1:34 PM
  • Why the second clicking will not tigger the AdvTreeSorter.Compare?

    If it happens even in case of simplest examples, then maybe contact the Technical Support.

    Also check the documentation, perhaps there is a special member such as ColumnHeader1.SortComparerReverse, which must be set too.


    • Marked as answer by gaxjyxq Sunday, February 23, 2020 10:51 PM
    Sunday, February 23, 2020 5:18 PM
  • Yes, the second clicking need to invoke the function "SortComparerReverse".

    Imports DevComponents.AdvTree

    Public Class Form1
      
        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            Dim oSorter As AdvTreeSorter
            oSorter = New AdvTreeSorter(AdvTreeSorter.SortOrder.Ascending)
            ColumnHeader1.SortComparer = oSorter
            ColumnHeader1.Sort()
        End Sub

        Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
            Dim oSorter As AdvTreeSorter
            oSorter = New AdvTreeSorter(AdvTreeSorter.SortOrder.Descending)
            ColumnHeader1.SortComparerReverse = oSorter
            ColumnHeader1.Sort()
        End Sub
    End Class

    Public Class AdvTreeSorter

        Implements Collections.IComparer
        Private m_oCulture As Globalization.CultureInfo = Globalization.CultureInfo.CurrentCulture

        Public Enum SortOrder
            Ascending
            Descending
        End Enum

        Private sortOrderModifier As Integer = 1

        Public Sub New(ByVal sortOrder As SortOrder)
            If sortOrder = sortOrder.Descending Then
                sortOrderModifier = -1
            ElseIf sortOrder = sortOrder.Ascending Then
                sortOrderModifier = 1
            End If
        End Sub

        Private Function Compare(ByVal o1 As Object, ByVal o2 As Object) As Integer _
            Implements Collections.IComparer.Compare
            Dim node1 As Node = CType(o1, Node)
            Dim node2 As Node = CType(o2, Node)
            Dim sTxt1 As String = node1.Text
            Dim sTxt2 As String = node2.Text

            Dim dDate1 As Date = Date.Parse(sTxt1, m_oCulture.DateTimeFormat)
            Dim dDate2 As Date = Date.Parse(sTxt2, m_oCulture.DateTimeFormat)

            Return sortOrderModifier * Date.Compare(dDate1, dDate2)
        End Function
    End Class

    • Marked as answer by gaxjyxq Sunday, February 23, 2020 10:51 PM
    Sunday, February 23, 2020 10:51 PM

All replies

  • Have you checked if ColumnHeader1_Click and AdvTreeSorter.Compare are called on second click? Using breakpoints, you can check the variables and behaviour during debugging.


    • Edited by Viorel_MVP Sunday, February 23, 2020 8:52 AM
    Sunday, February 23, 2020 8:51 AM
  • The NO.1, NO.3, NO.5... clicking invoked AdvTreeSorter.Compare, but the NO.2, NO.4, NO.6.. clicking did not invoke AdvTreeSorter.Compare. Thank you.
    Sunday, February 23, 2020 9:22 AM
  • Why the second clicking will not tigger the AdvTreeSorter.Compare?
    Sunday, February 23, 2020 12:05 PM
  • Hi,
    without knowing your whole code is impossible to find a problem . My demo works fine:

    Public Class Form81
    
      Private WithEvents lv As New ListView With {.Dock = DockStyle.Fill, .View = View.Details}
      Private columnSorter As New AdvTreeSorter
    
      Private Sub Form81_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        lv.ListViewItemSorter = columnSorter
        Me.Controls.Add(lv)
        lv.Columns.Add("Column")
    
        lv.Items.Add(New ListViewItem("2019/5/25"))
        lv.Items.Add(New ListViewItem("2019/12/25"))
        lv.Items.Add(New ListViewItem("2019/1/25"))
        lv.Items.Add(New ListViewItem("2019/11/25"))
        lv.Items.Add(New ListViewItem("2019/10/15"))
        lv.Items.Add(New ListViewItem("2019/1/30"))
      End Sub
    
    
      Private Sub ColumnHeader1_Click(sender As Object, e As EventArgs) Handles lv.ColumnClick
        If columnSorter.Order = SortOrder.Ascending Then
          columnSorter.Order = SortOrder.Descending
        Else
          columnSorter.Order = SortOrder.Ascending
        End If
        lv.Sort()
      End Sub
    
      Public Class AdvTreeSorter
    
        Implements Collections.IComparer
        Protected m_oCulture As Globalization.CultureInfo = Globalization.CultureInfo.CurrentCulture
    
        Private Function Compare(ByVal o1 As Object, ByVal o2 As Object) As Integer Implements Collections.IComparer.Compare
          If Order = SortOrder.None Then Return 0
    
          Dim sTxt1 = CType(o1, ListViewItem).Text
          Dim sTxt2 = CType(o2, ListViewItem).Text
    
          Dim dDate1 As Date = Date.Parse(sTxt1, m_oCulture.DateTimeFormat)
          Dim dDate2 As Date = Date.Parse(sTxt2, m_oCulture.DateTimeFormat)
    
          Return If(Order = SortOrder.Ascending, Date.Compare(dDate1, dDate2), -Date.Compare(dDate1, dDate2))
        End Function
    
        Public Property Order As SortOrder
    
      End Class
    
    End Class


    --
    Best Regards / Viele Grüße
    Peter Fleischer (former MVP for Developer Technologies)
    Homepage, Tipps, Tricks


    • Edited by Peter Fleischer Sunday, February 23, 2020 1:34 PM
    • Marked as answer by gaxjyxq Sunday, February 23, 2020 10:51 PM
    Sunday, February 23, 2020 1:34 PM
  • Why the second clicking will not tigger the AdvTreeSorter.Compare?

    If it happens even in case of simplest examples, then maybe contact the Technical Support.

    Also check the documentation, perhaps there is a special member such as ColumnHeader1.SortComparerReverse, which must be set too.


    • Marked as answer by gaxjyxq Sunday, February 23, 2020 10:51 PM
    Sunday, February 23, 2020 5:18 PM
  • OK, i will check it, thank you.
    Sunday, February 23, 2020 10:43 PM
  • Yes, the second clicking need to invoke the function "SortComparerReverse".

    Imports DevComponents.AdvTree

    Public Class Form1
      
        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            Dim oSorter As AdvTreeSorter
            oSorter = New AdvTreeSorter(AdvTreeSorter.SortOrder.Ascending)
            ColumnHeader1.SortComparer = oSorter
            ColumnHeader1.Sort()
        End Sub

        Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
            Dim oSorter As AdvTreeSorter
            oSorter = New AdvTreeSorter(AdvTreeSorter.SortOrder.Descending)
            ColumnHeader1.SortComparerReverse = oSorter
            ColumnHeader1.Sort()
        End Sub
    End Class

    Public Class AdvTreeSorter

        Implements Collections.IComparer
        Private m_oCulture As Globalization.CultureInfo = Globalization.CultureInfo.CurrentCulture

        Public Enum SortOrder
            Ascending
            Descending
        End Enum

        Private sortOrderModifier As Integer = 1

        Public Sub New(ByVal sortOrder As SortOrder)
            If sortOrder = sortOrder.Descending Then
                sortOrderModifier = -1
            ElseIf sortOrder = sortOrder.Ascending Then
                sortOrderModifier = 1
            End If
        End Sub

        Private Function Compare(ByVal o1 As Object, ByVal o2 As Object) As Integer _
            Implements Collections.IComparer.Compare
            Dim node1 As Node = CType(o1, Node)
            Dim node2 As Node = CType(o2, Node)
            Dim sTxt1 As String = node1.Text
            Dim sTxt2 As String = node2.Text

            Dim dDate1 As Date = Date.Parse(sTxt1, m_oCulture.DateTimeFormat)
            Dim dDate2 As Date = Date.Parse(sTxt2, m_oCulture.DateTimeFormat)

            Return sortOrderModifier * Date.Compare(dDate1, dDate2)
        End Function
    End Class

    • Marked as answer by gaxjyxq Sunday, February 23, 2020 10:51 PM
    Sunday, February 23, 2020 10:51 PM