Results 1 to 11 of 11

Thread: How can i sort a Listview Control?

  1. #1

    Thread Starter
    New Member
    Join Date
    Jan 2000
    Posts
    4

    Post

    hello everyone

    the listview control in visual basic can sort on any column simply. my problem is that it behaves like it is sorting strings. i cannot get it to correctly sort on numbers or dates.

    eg. it sorts numbers 1 to 23 like this....

    1
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    2
    20
    21
    22
    23
    24
    3
    4
    5
    6
    7
    8
    9

    same problem with dates it thinks they are strings. i have investigated the following:
    (*) the columnheader objet does not have a property where i can define the data type of the column values that it will hold
    (*) you cannot create a hidden column to sort on. ie. somehow fake the sort

    the windows explorer uses a similar or probably the same control. click on the size and see the column values are not sorted as if they were strings, they are actually sorted in correct order of file size.

    ANY IDEAS/SOLUTION/ALTERNATIVE.


    also see the control (listview) used by winzip. do you think these are the same as what we the vb-developers have been provided with.


    [This message has been edited by badal (edited 01-28-2000).]

  2. #2
    Guest

    Post

    Hello badal,

    The only way I was able to get around this was to format my numbers with 0.

    1 = 01
    2 = 02

    That works out the sorting.
    Good Luck

    ------------------
    Boothman
    There is a war out there and it is about who controls the information, it's all about the information.

  3. #3
    Addicted Member
    Join Date
    Jan 2000
    Location
    Fresno, California, USA
    Posts
    195

    Post

    These are as good as you're going to get. Unfortunately, ListView uses a simple sort that doesn't take into account whether it's a date or an integer or a string. It just treats everything like a string.

  4. #4

    Thread Starter
    New Member
    Join Date
    Jan 2000
    Posts
    4

    Post

    thanx guys,

    that's exactly what i thought, vb listview cannot handle anything but strings. this does not solve my problem, i wonder how they have done in winzip and windows explorer or what control are they using. thanx anyway.

    do you know of an equivalent control, anything but not the grid unless it has a columnclick event like listview does?

  5. #5
    Fanatic Member
    Join Date
    Jan 2000
    Location
    Mobile, AL, USA
    Posts
    600

    Post

    Greetings Badal.

    As for Dates, if you format the values so that the years are first, then the months, then the days, I believe that ascending and descending sorts will be correct. I'm not sure about this, however, because I haven't tested it.

    For example:
    Code:
    format(Date,"yyyy/mm/dd")
    Hope this helps.
    ------------------
    OneSource
    The truth may be out there, but it's in here too!
    .

    [This message has been edited by OneSource (edited 01-28-2000).]

  6. #6
    Serge's Avatar
    Join Date
    Feb 1999
    Location
    Scottsdale, Arizona, USA
    Posts
    2,744

    Post

    Here is an example of how to sort the ListView by Date or Number. Copy this code to a module:

    VB Code:
    1. Private Declare Function LockWindowUpdate Lib "user32" (ByVal hWndLock As Long) As Long
    2. Public Enum eSortType
    3.     eByDate = 1
    4.     eByNumber = 2
    5.     eByString = 3
    6. End Enum
    7. Public Sub SortListView(pListView As ListView, pSortType As eSortType, pColumnHeaderIndex As Integer)
    8.     Dim l As Long
    9.     Dim strFormat As String
    10.     Dim strData() As String
    11.     Dim lngCursor As Long
    12.     Dim lngIndex As Long
    13.    
    14.     On Error Resume Next
    15.    
    16.    
    17.     With pListView
    18.         ' Display the hourglass cursor whilst sorting
    19.         lngCursor = .MousePointer
    20.         .MousePointer = vbHourglass
    21.        
    22.         ' Prevent the ListView control from updating on screen -
    23.         ' this is to hide the changes being made to the listitems
    24.         ' and also to speed up the sort
    25.         LockWindowUpdate .hWnd
    26.        
    27.         lngIndex = pColumnHeaderIndex - 1
    28.         Select Case pSortType
    29.             Case eByDate
    30.                 ' Sort by date.
    31.                 strFormat = "YYYYMMDDHhNnSs"
    32.                 With .ListItems
    33.                     If (lngIndex > 0) Then
    34.                         For l = 1 To .Count
    35.                             With .Item(l).ListSubItems(lngIndex)
    36.                                 .Tag = .Text & vbNullChar & .Tag
    37.                                 If IsDate(.Text) Then
    38.                                     .Text = Format(CDate(.Text), _
    39.                                                         strFormat)
    40.                                 Else
    41.                                     .Text = ""
    42.                                 End If
    43.                             End With
    44.                         Next l
    45.                     Else
    46.                         For l = 1 To .Count
    47.                             With .Item(l)
    48.                                 .Tag = .Text & vbNullChar & .Tag
    49.                                 If IsDate(.Text) Then
    50.                                     .Text = Format(CDate(.Text), _
    51.                                                         strFormat)
    52.                                 Else
    53.                                     .Text = ""
    54.                                 End If
    55.                             End With
    56.                         Next l
    57.                     End If
    58.                 End With
    59.                
    60.                 With .ListItems
    61.                     If (lngIndex > 0) Then
    62.                         For l = 1 To .Count
    63.                             With .Item(l).ListSubItems(lngIndex)
    64.                                 strData = Split(.Tag, vbNullChar)
    65.                                 .Text = strData(0)
    66.                                 .Tag = strData(1)
    67.                             End With
    68.                         Next l
    69.                     Else
    70.                         For l = 1 To .Count
    71.                             With .Item(l)
    72.                                 strData = Split(.Tag, vbNullChar)
    73.                                 .Text = strData(0)
    74.                                 .Tag = strData(1)
    75.                             End With
    76.                         Next l
    77.                     End If
    78.                 End With
    79.                
    80.             Case eByNumber
    81.                 ' Sort Numerically
    82.                 strFormat = String(30, "0") & "." & String(30, "0")
    83.                 With .ListItems
    84.                     If (lngIndex > 0) Then
    85.                         For l = 1 To .Count
    86.                             With .Item(l).ListSubItems(lngIndex)
    87.                                 .Tag = .Text & vbNullChar & .Tag
    88.                                 If IsNumeric(.Text) Then
    89.                                     If CDbl(.Text) >= 0 Then
    90.                                         .Text = Format(CDbl(.Text), _
    91.                                             strFormat)
    92.                                     Else
    93.                                         .Text = "&" & InvertNumber( _
    94.                                             Format(0 - CDbl(.Text), _
    95.                                             strFormat))
    96.                                     End If
    97.                                 Else
    98.                                     .Text = ""
    99.                                 End If
    100.                             End With
    101.                         Next l
    102.                     Else
    103.                         For l = 1 To .Count
    104.                             With .Item(l)
    105.                                 .Tag = .Text & vbNullChar & .Tag
    106.                                 If IsNumeric(.Text) Then
    107.                                     If CDbl(.Text) >= 0 Then
    108.                                         .Text = Format(CDbl(.Text), _
    109.                                             strFormat)
    110.                                     Else
    111.                                         .Text = "&" & InvertNumber( _
    112.                                             Format(0 - CDbl(.Text), _
    113.                                             strFormat))
    114.                                     End If
    115.                                 Else
    116.                                     .Text = ""
    117.                                 End If
    118.                             End With
    119.                         Next l
    120.                     End If
    121.                 End With
    122.                 With .ListItems
    123.                     If (lngIndex > 0) Then
    124.                         For l = 1 To .Count
    125.                             With .Item(l).ListSubItems(lngIndex)
    126.                                 strData = Split(.Tag, vbNullChar)
    127.                                 .Text = strData(0)
    128.                                 .Tag = strData(1)
    129.                             End With
    130.                         Next l
    131.                     Else
    132.                         For l = 1 To .Count
    133.                             With .Item(l)
    134.                                 strData = Split(.Tag, vbNullChar)
    135.                                 .Text = strData(0)
    136.                                 .Tag = strData(1)
    137.                             End With
    138.                         Next l
    139.                     End If
    140.                 End With
    141.            
    142.             Case Else
    143.         End Select
    144.         .SortOrder = (.SortOrder + 1) Mod 2
    145.         .SortKey = pColumnHeaderIndex - 1
    146.         .Sorted = True
    147.  
    148.         ' Unlock the list window so that the OCX can update it
    149.         LockWindowUpdate 0&
    150.        
    151.         ' Restore the previous cursor
    152.         .MousePointer = lngCursor
    153.     End With
    154. End Sub
    155.  
    156. Private Function InvertNumber(ByVal pNumber As String) As String
    157.     Static i As Integer
    158.     For i = 1 To Len(pNumber)
    159.         Select Case Mid$(pNumber, i, 1)
    160.         Case "-": Mid$(pNumber, i, 1) = " "
    161.         Case "0": Mid$(pNumber, i, 1) = "9"
    162.         Case "1": Mid$(pNumber, i, 1) = "8"
    163.         Case "2": Mid$(pNumber, i, 1) = "7"
    164.         Case "3": Mid$(pNumber, i, 1) = "6"
    165.         Case "4": Mid$(pNumber, i, 1) = "5"
    166.         Case "5": Mid$(pNumber, i, 1) = "4"
    167.         Case "6": Mid$(pNumber, i, 1) = "3"
    168.         Case "7": Mid$(pNumber, i, 1) = "2"
    169.         Case "8": Mid$(pNumber, i, 1) = "1"
    170.         Case "9": Mid$(pNumber, i, 1) = "0"
    171.         End Select
    172.     Next
    173.     InvertNumber = pNumber
    174. End Function

    Usage: SortListView ListView, SortType, ColumnHeaderIndex

    Exaple:

    VB Code:
    1. Private Sub ListView1_ColumnClick(ByVal ColumnHeader As MSComctlLib.ColumnHeader)
    2.     Select Case ColumnHeader
    3.         Case "DATE"
    4.             SortListView ListView1, eByDate, ColumnHeader.Index
    5.         Case "NUMBER"
    6.             SortListView ListView1, eByNumber, ColumnHeader.Index
    7.     End Select
    8. End Sub

  7. #7
    Junior Member
    Join Date
    Jan 1999
    Posts
    26

    Post


  8. #8
    Lively Member Geemark's Avatar
    Join Date
    Aug 2002
    Location
    At the pc wasting my worthless time
    Posts
    89
    I have done exactly what was in that sample, but it still does not sort by numbers even if I use "eByNumber".
    What is wrong??

    All I get is this:
    1
    11
    2

    Instead of:
    1
    2
    11


    Please help
    Machine Language: You try to shoot yourself in
    the foot only to discover you must first reinvent the
    gun, gunpowder, the bullet, and your foot.

  9. #9
    New Member
    Join Date
    May 2001
    Location
    Michigan, U.S.
    Posts
    7

    Question



    Not sure if you are getting your data from a database or not, but you can always write a method--er--sub(damn Java!) to requery the data with the ORDER BY clause on the numeric field and repopulate the listView based on that. This assumes, of course that there isn't a huge amount of data displayed in the listView. Also, this could be a big waste of time if you aren't populating with a database.

    Anyway, good luck!

    VB 5.0 Enterprise
    VB 6.0 Enterprise
    Sybase
    MSAccess
    Windows 98 SE
    Windows 2000 SR1

  10. #10
    Lively Member Geemark's Avatar
    Join Date
    Aug 2002
    Location
    At the pc wasting my worthless time
    Posts
    89
    I am using a database, but do not want to requery every time the user changes the sorting order. However I sorted it out!
    Machine Language: You try to shoot yourself in
    the foot only to discover you must first reinvent the
    gun, gunpowder, the bullet, and your foot.

  11. #11
    old fart Frans C's Avatar
    Join Date
    Oct 1999
    Location
    the Netherlands
    Posts
    2,926
    MVPS has some code on sorting listviews.
    http://www.mvps.org/vbnet/index.html...rtcallback.htm

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width