Solved

vb.net listview sort items

Posted on 2013-11-01
7
654 Views
Last Modified: 2013-11-02
Hello,
I am trying to sort some number with this listview

from this
50
500
1,500
900
5,600

into this
5,600
1,500
900
500
50

but its not working maybe cus of the comma, how can I make it work ?

    Private m_SortingColumn As ColumnHeader
    Private Sub lstMain_ColumnClick(ByVal sender As System.Object, ByVal e As System.Windows.Forms.ColumnClickEventArgs) Handles lstMain.ColumnClick
        Dim new_sorting_column As ColumnHeader = lstMain.Columns(e.Column)

        Dim sort_order As System.Windows.Forms.SortOrder
        If m_SortingColumn Is Nothing Then
            sort_order = SortOrder.Ascending
        Else
            If new_sorting_column.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 = new_sorting_column
        If sort_order = SortOrder.Ascending Then
            m_SortingColumn.Text = "> " & m_SortingColumn.Text
        Else
            m_SortingColumn.Text = "< " & m_SortingColumn.Text
        End If

        lstMain.ListViewItemSorter = New ListViewComparer(e.Column, sort_order)
        lstMain.Sort()
    End Sub

Open in new window


Public 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

        ' Compare the items in the appropriate column for objects x and y.
        Public Function Compare(ByVal x As Object, ByVal y As Object) As Integer Implements System.Collections.IComparer.Compare
            Compare = Nothing

                Dim item_x As ListViewItem = DirectCast(x, ListViewItem)
                Dim item_y As ListViewItem = DirectCast(y, ListViewItem)

                ' Get the sub-item values.
                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

                ' Compare them.
                If m_SortOrder = SortOrder.Ascending Then
                    If IsNumeric(string_x) And IsNumeric(string_y) Then
                        Return Val(string_x).CompareTo(Val(string_y))
                    ElseIf IsDate(string_x) And IsDate(string_y) Then
                        Return DateTime.Parse(string_x).CompareTo(DateTime.Parse(string_y))
                    Else
                        Return String.Compare(string_x, string_y)
                    End If
                Else
                    If IsNumeric(string_x) And IsNumeric(string_y) Then
                        Return Val(string_y).CompareTo(Val(string_x))
                    ElseIf IsDate(string_x) And IsDate(string_y) Then
                        Return DateTime.Parse(string_y).CompareTo(DateTime.Parse(string_x))
                    Else
                        Return String.Compare(string_y, string_x)
                    End If
                End If

        End Function
    End Class

Open in new window

0
Comment
Question by:XK8ER
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
  • 3
7 Comments
 
LVL 44

Expert Comment

by:AndyAinscow
ID: 39618381
Yes, you are sorting strings and 5,300 is less than 6 as a string.

In your sort function you need to convert the string value (900 or 5,300 or..) into the numeric value - eg. with a TryParse.  Then compare the numeric values to determine the
sort order.
0
 
LVL 1

Author Comment

by:XK8ER
ID: 39618385
thanks AndyAinscow, how would I do that?
0
 
LVL 44

Expert Comment

by:AndyAinscow
ID: 39618397
eg.
instead of
                    If IsNumeric(string_x) And IsNumeric(string_y) Then
                        Return Val(string_x).CompareTo(Val(string_y))

use something like (I usually code in c# or C++ so this might need slight modification)

                    If IsNumeric(string_x) And IsNumeric(string_y) Then
                        Return Int.Parse(string_x) < Int.Parse(string_y)
0
Creating Instructional Tutorials  

For Any Use & On Any Platform

Contextual Guidance at the moment of need helps your employees/users adopt software o& achieve even the most complex tasks instantly. Boost knowledge retention, software adoption & employee engagement with easy solution.

 
LVL 1

Author Comment

by:XK8ER
ID: 39618412
Integer.Parse

nothing happens with the code.. meaning nothing gets sorted with numbers
0
 
LVL 1

Author Comment

by:XK8ER
ID: 39618440
I think i've found a solution, right before

If m_SortOrder = SortOrder.Ascending Then

I added this and it works..

                string_y = string_y.Replace(",", "")
                string_x = string_x.Replace(",", "")

Open in new window

0
 
LVL 44

Expert Comment

by:AndyAinscow
ID: 39618461
That is fine - that is a VB method to convert a string to a number.    

According to the help files the Val(...) would stop with the first non number in the string so 5,300 would be converted to 5 - hence your problem
0
 
LVL 40

Accepted Solution

by:
Jacques Bourgeois (James Burger) earned 500 total points
ID: 39618849
IsNumeric and TryParse are dependant on the culture. They will work with the current set of data only if the Control Panel or the Culture of the application have the thousands separator set to a coma, which is not the case for everyone. In some cultures, the coma is used as the decimal separator, so the stuff would end up all wrong because 5,600 would be seen as 5.6.

The Replace does not have that limitation and is thus a better solution.
0

Featured Post

Salesforce Made Easy to Use

On-screen guidance at the moment of need enables you & your employees to focus on the core, you can now boost your adoption rates swiftly and simply with one easy tool.

Question has a verified solution.

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

Today I had a very interesting conundrum that had to get solved quickly. Needless to say, it wasn't resolved quickly because when we needed it we were very rushed, but as soon as the conference call was over and I took a step back I saw the correct …
It was really hard time for me to get the understanding of Delegates in C#. I went through many websites and articles but I found them very clumsy. After going through those sites, I noted down the points in a easy way so here I am sharing that unde…
There's a multitude of different network monitoring solutions out there, and you're probably wondering what makes NetCrunch so special. It's completely agentless, but does let you create an agent, if you desire. It offers powerful scalability …
NetCrunch network monitor is a highly extensive platform for network monitoring and alert generation. In this video you'll see a live demo of NetCrunch with most notable features explained in a walk-through manner. You'll also get to know the philos…

623 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