I cannot figure out why this is not working. I have a ListView
that I would like to be able to sort in both ascending and descending order. It appears when stepping through the code line by line that all goes well except lvItems.Sorting
will not equal Descending
. It is in a constant loop between None{0} and Ascending{1}.
Here is the Form class:
Private Sub lvItems_ColumnClick(sender As Object, e As System.Windows.Forms.ColumnClickEventArgs) Handles lvItems.ColumnClick
' If current column is not the previously clicked column
' Add
If e.Column <> sortColumn Then
' Set the sort column to the new column
sortColumn = e.Column
'Default to ascending sort order
lvItems.Sorting = SortOrder.Ascending
Else
'Flip the sort order
If lvItems.Sorting = SortOrder.Ascending Then
lvItems.Sorting = SortOrder.Descending
Else
lvItems.Sorting = SortOrder.Ascending
End If
End If
'Set the ListviewItemSorter property to a new ListviewItemComparer object
Me.lvItems.ListViewItemSorter = New ListViewItemComparer(e.Column, lvItems.Sorting)
' Call the sort method to manually sort
lvItems.Sort()
End Sub
And here is the ListViewItemComparer
Class:
Public Class ListViewItemComparer
Implements IComparer
Private col As Integer
Private order As SortOrder
Public Sub New()
col = 0
order = SortOrder.Ascending
End Sub
Public Sub New(column As Integer, order As SortOrder)
col = column
Me.order = order
End Sub
Public Function Compare(x As Object, y As Object) As Integer Implements System.Collections.IComparer.Compare
Dim returnVal As Integer = -1
Try
' Attempt to parse the two objects as DateTime
Dim firstDate As System.DateTime = DateTime.Parse(CType(x, ListViewItem).SubItems(col).Text)
Dim secondDate As System.DateTime = DateTime.Parse(CType(y, ListViewItem).SubItems(col).Text)
' Compare as date
returnVal = DateTime.Compare(firstDate, secondDate)
Catch ex As Exception
' If date parse failed then fall here to determine if objects are numeric
If IsNumeric(CType(x, ListViewItem).SubItems(col).Text) And
IsNumeric(CType(y, ListViewItem).SubItems(col).Text) Then
' Compare as numeric
returnVal = Val(CType(x, ListViewItem).SubItems(col).Text).CompareTo(Val(CType(y, ListViewItem).SubItems(col).Text))
Else
' If not numeric then compare as string
returnVal = [String].Compare(CType(x, ListViewItem).SubItems(col).Text, CType(y, ListViewItem).SubItems(col).Text)
End If
End Try
' If order is descending then invert value
If order = SortOrder.Descending Then
returnVal *= -1
End If
Return returnVal
End Function
End Class
No matter what data I put in I only seem to get ascending order. Let me know if more information is necessary.
I was able to resolve issue thanks to @jmcilhinney's comment. Instead of using both Sorting
and ListViewItemSorter
, I created a string variable ordering
and assigned it the appropriate sort order (see below for final solution).
'If current column is not the previously clicked column
'Add
If e.Column <> sortColumn Then
' Set the sort column to the new column
sortColumn = e.Column
'Default to ascending sort order
ordering = "Ascending"
Else
'Flip the sort order
If ordering = "Ascending" Then
ordering = "Descending"
Else
ordering = "Ascending"
End If
End If
'Set the ListviewItemSorter property to a new ListviewItemComparer object
lvItems.ListViewItemSorter = New ListViewItemComparer(e.Column, ordering)
'Call the sort method to manually sort
lvItems.Sort()