locked
How to sort items in a listview control by clicking column headers

    Question

  • I have a listview control that I have a multitude of files displayed, in addition there are 6 columns in the listview that shows information about the file in question.

    I have gotten this far, but my question is this: how do I allow the user to sort the listview by clicking on the column headers. Like one can do in list view in a Windows window?


    • Edited by turtlbrdr Tuesday, February 14, 2012 8:36 PM
    Tuesday, February 14, 2012 3:32 PM

Answers

  • here is a good example of how to sort a ListView by clicking on the column header

    http://msdn.microsoft.com/en-us/library/ms996467.aspx

    but as I mentioned why not use a DataGridView? Try this in an app with a Button and DataGridView on the Form. Click the button, then you simply need to click the DGV column headers to sort. you can easily add the file info as records in the datatable

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
            Dim dtFiles As New DataTable
            dtFiles.Columns.Add("FileName", GetType(String))
            dtFiles.Columns.Add("FileSize", GetType(Integer))
            dtFiles.Columns.Add("DateCreated", GetType(Date))
    
            Dim rndm As New Random
            For i As Integer = 1 To 10
                dtFiles.Rows.Add(Chr(rndm.Next(65, 91)), rndm.Next(1000, 5001), Today.AddDays(rndm.Next(-100, 101)))
            Next
    
            DataGridView1.DataSource = dtFiles.DefaultView
        End Sub

    Tuesday, February 14, 2012 9:11 PM

All replies

  • are you drawing your own ListBox, because the standard ListBox does not have Column headers?

    why not use a DataGridView that has that functionality?

    Tuesday, February 14, 2012 4:20 PM
  • are you drawing your own ListBox, because the standard ListBox does not have Column headers?

    why not use a DataGridView that has that functionality?

    Maybe I'm using the wrong term? I'm refering to the tops of the columns where in windows explorer it will put stuff like "Name" "Contributing Artists" and stuff like that...

    and shit, yes I did use the wrong term I'm using a listview control instead

    Tuesday, February 14, 2012 8:36 PM
  • here is a good example of how to sort a ListView by clicking on the column header

    http://msdn.microsoft.com/en-us/library/ms996467.aspx

    but as I mentioned why not use a DataGridView? Try this in an app with a Button and DataGridView on the Form. Click the button, then you simply need to click the DGV column headers to sort. you can easily add the file info as records in the datatable

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
            Dim dtFiles As New DataTable
            dtFiles.Columns.Add("FileName", GetType(String))
            dtFiles.Columns.Add("FileSize", GetType(Integer))
            dtFiles.Columns.Add("DateCreated", GetType(Date))
    
            Dim rndm As New Random
            For i As Integer = 1 To 10
                dtFiles.Rows.Add(Chr(rndm.Next(65, 91)), rndm.Next(1000, 5001), Today.AddDays(rndm.Next(-100, 101)))
            Next
    
            DataGridView1.DataSource = dtFiles.DefaultView
        End Sub

    Tuesday, February 14, 2012 9:11 PM
  • I have a listview control that I have a multitude of files displayed, in addition there are 6 columns in the listview that shows information about the file in question.

    I have gotten this far, but my question is this: how do I allow the user to sort the listview by clicking on the column headers. Like one can do in list view in a Windows window?


    you'd use a comparer class (this sorts dates, numbers, + strings):

    Public Class clsListViewItemComparer
        Implements IComparer
    
        Private _Column As Integer
        Private _Numeric As Boolean = False
        Private _isDate As Boolean = False
        Private _sortAscending As Boolean = False
    
        Public Property Column() As Integer
            Get
                Return _Column
            End Get
            Set(ByVal Value As Integer)
                _Column = Value
            End Set
        End Property
    
        Public Property Numeric() As Boolean
            Get
                Return _Numeric
            End Get
            Set(ByVal Value As Boolean)
                _Numeric = Value
            End Set
        End Property
    
        Public Property isDate() As Boolean
            Get
                Return _isDate
            End Get
            Set(ByVal Value As Boolean)
                _isDate = Value
            End Set
        End Property
    
        Public Property sortAscending() As Boolean
            Get
                Return _sortAscending
            End Get
            Set(ByVal Value As Boolean)
                _sortAscending = Value
            End Set
        End Property
    
        Public Sub New(ByVal columnIndex As Integer)
            Column = columnIndex
        End Sub
    
        Public Function Compare(ByVal x As Object, ByVal y As Object) As Integer Implements System.Collections.IComparer.Compare
            Dim ListX As ListViewItem = CType(x, ListViewItem)
            Dim ListY As ListViewItem = CType(y, ListViewItem)
    
            If Numeric Then
                ' Convert column text to numbers before comparing.
                ' If the conversion fails, just use the value 0.
                Dim ListXVal, ListYVal As Decimal
                Try
                    ListXVal = Decimal.Parse(Replace(ListX.SubItems(Column).Text, "£", ""))
                Catch
                    ListXVal = 0
                End Try
    
                Try
                    ListYVal = Decimal.Parse(Replace(ListY.SubItems(Column).Text, "£", ""))
                Catch
                    ListYVal = 0
                End Try
    
                If Not sortAscending Then
                    Return Decimal.Compare(ListYVal, ListXVal)
                Else
                    Return Decimal.Compare(ListXVal, ListYVal)
                End If
    
            ElseIf isDate Then
                Dim ListXVal, ListYVal As Date
                Try
                    ListXVal = Date.Parse(ListX.SubItems(Column).Text)
                Catch
                    'ListXVal = 0
                End Try
    
                Try
                    ListYVal = Date.Parse(ListY.SubItems(Column).Text)
                Catch
                    'ListYVal = 0
                End Try
    
                If Not sortAscending Then
                    Return Date.Compare(ListYVal, ListXVal)
                Else
                    Return Date.Compare(ListXVal, ListYVal)
                End If
    
            Else
                ' Keep the column text in its native string format
                ' and perform an alphabetic comparison.
                Dim ListXText As String = ListX.SubItems(Column).Text
                Dim ListYText As String = ListY.SubItems(Column).Text
    
                If Not sortAscending Then
                    Return String.Compare(ListYText, ListXText)
                Else
                    Return String.Compare(ListXText, ListYText)
                End If
    
            End If
    
        End Function
    End Class
    

    this is the listview code:

    Private Sub ListView1_ColumnClick(ByVal sender As Object, ByVal e As System.Windows.Forms.ColumnClickEventArgs) Handles ListView1.ColumnClick
        Static SortOrder() As String = {"descending", "descending", "descending"}
        Dim Sorter As New clsListViewItemComparer(e.Column)
        If e.Column = 0 Then 'numeric column
            Sorter.Numeric = True
        End If
        If e.Column = 1 Then 'date column
            Sorter.isDate = True
        End If
        If SortOrder(e.Column) = "descending" Then
            SortOrder(e.Column) = "ascending"
            Sorter.sortAscending = True
        Else
            SortOrder(e.Column) = "descending"
        End If
    
        ListView1.ListViewItemSorter = Sorter
        ListView1.Sort()
        ListView1.ListViewItemSorter = Nothing
    
    End Sub


    thanks for any help

    Wednesday, February 15, 2012 9:14 AM