Solved

Sorting Numerically in a ListView

Posted on 2006-07-04
4
272 Views
Last Modified: 2010-04-23
I am using the following code to allow me to sort a listview by clicking on the column headers

Public m_SortingColumn As ColumnHeader

Class ListViewComparer
        Implements IComparer

        Private m_ColumnNumber As Integer
        Private m_SortOrder As SortOrder

        Public Sub New(ByVal column_number As Integer, ByVal sort_order As SortOrder)
            m_ColumnNumber = column_number
            m_SortOrder = sort_order
        End Sub

        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 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
            If m_SortOrder = SortOrder.Ascending Then
                Return String.Compare(string_x, string_y)
            Else
                Return String.Compare(string_y, string_x)
            End If
        End Function
    End Class

 Private Sub lstvwColumns_ColumnClick(ByVal sender As Object, ByVal e As System.Windows.Forms.ColumnClickEventArgs) Handles lstvwColumns.ColumnClick
        Dim colTemp As ColumnHeader = lstvwColumns.Columns(e.Column)
        Dim sort_order As System.Windows.Forms.SortOrder
        If m_SortingColumn Is Nothing Then
            sort_order = SortOrder.Ascending
        Else
            If colTemp.Equals(m_SortingColumn) Then
                If m_SortingColumn.Text.StartsWith("> ") Then
                    sort_order = SortOrder.Descending
                Else
                    sort_order = SortOrder.Ascending
                End If
            Else
                sort_order = SortOrder.Ascending
            End If
            m_SortingColumn.Text = m_SortingColumn.Text.Substring(2)
        End If
        m_SortingColumn = colTemp
        If sort_order = SortOrder.Ascending Then
            m_SortingColumn.Text = "> " & m_SortingColumn.Text
        Else
            m_SortingColumn.Text = "< " & m_SortingColumn.Text
        End If
        lstvwColumns.ListViewItemSorter = New ListViewComparer(e.Column, sort_order)
        lstvwColumns.Sort()
    End Sub

This works great, however, when it sorts a numeric column it sorts one digit at a time rather than whole numbers ie: it puts 1000 before 2 when sorting ascending.
Is there anyway my code can by modified to allow any numeric columns to be correctly numerically sorted without affecting the sort order of normal text columns

Thanks
0
Comment
Question by:kiranboi
  • 2
4 Comments
 
LVL 9

Expert Comment

by:lojk
ID: 17037642
load your values into a dataset, ensuring your numeric column is set to be a number rather than text and bind the listview to that rather than your list.
0
 

Author Comment

by:kiranboi
ID: 17037652
any chance of a code example. Im a newbie :o)
0
 
LVL 34

Accepted Solution

by:
Sancler earned 500 total points
ID: 17038120
As a non-dataset approach, you could try adding .PadLeft(10, " ") to

                string_x = item_x.SubItems(m_ColumnNumber).Text

and

                string_y = item_y.SubItems(m_ColumnNumber).Text

in your Public Function Compare.  That is, change them, respectively, to

                string_x = item_x.SubItems(m_ColumnNumber).Text.PadLeft(10, " ")

and

                string_y = item_y.SubItems(m_ColumnNumber).Text.PadLeft(10, " ")


The effect of this would be to base the string comparison on the full 10 character, space-padded, string that resulted in each case and, for numerals, (using '-' to indicate the spaces just for the purposes of this post) "---------2" would be 'less than' "------1000".

It's a bit rough and ready as it stands.  The 10 is fairly arbitrary, but assumes that none of the numbers that you want to sort will be represented by more than 10 characters.  It will not take account of numerals expressed to different degrees of decimal precision: or of the fact that numbers preceded by a minus sign should be treated as 'less than' those not so preceded.  It could possibly have some impact on some alpha sorts.  But it could be refined to cope with each of those problems if they would, in practice, be problems.

Roger
0
 

Author Comment

by:kiranboi
ID: 17040689
That'll do nicely. Thanks Roger
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

I think the Typed DataTable and Typed DataSet are very good options when working with data, but I don't like auto-generated code. First, I create an Abstract Class for my DataTables Common Code.  This class Inherits from DataTable. Also, it can …
Parsing a CSV file is a task that we are confronted with regularly, and although there are a vast number of means to do this, as a newbie, the field can be confusing and the tools can seem complex. A simple solution to parsing a customized CSV fi…
Migrating to Microsoft Office 365 is becoming increasingly popular for organizations both large and small. If you have made the leap to Microsoft’s cloud platform, you know that you will need to create a corporate email signature for your Office 365…
Sending a Secure fax is easy with eFax Corporate (http://www.enterprise.efax.com). First, just open a new email message. In the To field, type your recipient's fax number @efaxsend.com. You can even send a secure international fax — just include t…

867 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

16 Experts available now in Live!

Get 1:1 Help Now