Question Sorting Specific Column in ListView

digitaldrew

Well-known member
Joined
Nov 10, 2012
Messages
167
Programming Experience
Beginner
Hello Everyone..I hope someone can help me out a little here. I'm currently loading some information into a ListView box and I'm trying to sort the items by the date shown - but it doesn't appear to be working.

This is how the ListView normally looks
eaQSgiX.jpg


I've gone in and added the following code into my ListView1_ColumnClick

VB.NET:
    Private Sub ListView1_ColumnClick(ByVal sender As Object, ByVal e As System.Windows.Forms.ColumnClickEventArgs) Handles ListView1.ColumnClick
        ' Determine if the clicked column is already the column that is 
        ' being sorted.
        If (e.Column = ListView1Sorter.SortColumn) Then
            ' Reverse the current sort direction for this column.
            If (ListView1Sorter.Order = SortOrder.Ascending) Then
                ListView1Sorter.Order = SortOrder.Descending
            Else
                ListView1Sorter.Order = SortOrder.Ascending
            End If
        Else
            ' Set the column number that is to be sorted; default to ascending.
            ListView1Sorter.SortColumn = e.Column
            ListView1Sorter.Order = SortOrder.Ascending
        End If

        ' Perform the sort with these new sort options.
        ListView1.Sort()
    End Sub

Now this does seam to arrange them, but not exactly how I'd like. If you look at the screenshot below you'll see how the code above arranges the items..
pvNQzWN.jpg


As you see by looking at the screenshot above, it has arranged the items but it looks like it arranged them by the first set of numbers, not the actual date. How would I arrange these so the item with the oldest date would actually show up first?
 
The problem is that everything in a ListView is text, so sorting a ListView as is is simply going to sort "alphabetically". If you want the data treated as dates then you have to parse the text into Dates and then compare them as Dates. As such, your IComparer might look something like this:
Public Class ListViewItemComparer
    Implements IComparer

    Private col As Integer

    Public Sub New()
        col = 0
    End Sub

    Public Sub New(ByVal column As Integer)
        col = column
    End Sub

    Public Function Compare(ByVal x As Object, ByVal y As Object) As Integer Implements IComparer.Compare
        Dim item1 = DirectCast(x, ListViewItem)
        Dim item2 = DirectCast(y, ListViewItem)
        Dim text1 = item1.SubItems(col).Text
        Dim text2 = item2.SubItems(col).Text

        If col = 1 Then
            Dim date1 = Date.ParseExact(text1.Split(":"c)(1), "dd-MMM-yyyy", Nothing)
            Dim date2 = Date.ParseExact(text2.Split(":"c)(1), "dd-MMM-yyyy", Nothing)

            Return date1.CompareTo(date2)
        Else
            Return text1.CompareTo(text2)
        End If
    End Function
End Class
 
Thanks jmcil! This is exactly what I was thinking about your code looks similar to what I ended up doing.

Basically, I chopped of the "creation date:" portion with a split (like you did) and then converted the date (like you did)

One other small question, is there a way to sort the listview automatically as each new item is added in there? Right now it appears to work fine if you click on the column, but I would rather have it add each item alphabetically rather than having to wait for it to check all of them and then click the column to arrange it..

Thanks again!
 
UPDATE..I was able to fix my second question "is there a way to sort the listview automatically as each new item is added in there?" using this code:

VB.NET:
ListView1Sorter.SortColumn = 1
ListView1Sorter.Order = SortOrder.Ascending
ListView1.Sort()
 
Back
Top