SUMMARY
This step-by-step article describes how to sort a
ListView control by a column in your Visual Basic .NET or Visual Basic 2005 application.
When you are working with the
ListView control, you may want to sort its contents based on a specific
column. An example of this kind of functionality occurs in a Windows Explorer
program when you view the contents of a folder on your hard disk. In Details
view, Windows Explorer displays information about the files in that folder. For
example, you see the file name, the file size, the file type, and the date that
the file was modified. When you click one of the column headers, the list is
sorted in ascending order based on that column. When you click the same column
header again, the column is sorted in descending order.
The example
in this article defines a class that implements the
IComparer interface. Additionally, this example uses the
Compare method of the
CaseInsenstiveComparer class to perform the actual comparison of the items. Note that
this method of comparison is not case sensitive ("Apple" is considered to be
the same as "apple"). Also, note that all of the columns in this example are
sorted in a "text" manner. If you want to sort in a different manner (such as
numerically), you can replace the following line of code with whichever
approach to sorting that you want to use:
compareResult = ObjectCompare.Compare(listviewX.SubItems(ColumnToSort).Text, listviewY.SubItems(ColumnToSort).Text)
back to the top
How to Build the Sample Project
- Create a new Visual Basic .NET or Visual Basic 2005 Windows Application project.
Form1 is created by default.
Note You must change the code in Visual Basic 2005. By default, Visual Basic creates two files for the project when you create a Windows Forms project. If the form is named Form1, the two files that represent the form are named Form1.vb and Form1.Designer.vb. You write the code in the Form1.vb file. The Windows Forms Designer writes the code in the Form1.Designer.vb file. The Windows Forms Designer uses the partial keyword to divide the implementation of Form1 into two separate files. This behavior prevents the designer-generated code from being interspersed with your code.
For more information about the new Visual Basic 2005 language enhancements, visit the following Microsoft Developer Network (MSDN) Web site:
For more information about partial classes and the Windows Forms Designer, visit the following MSDN Web site:
- Add a ListView control to Form1. Size the form to be several inches wide by
several inches tall.
- Paste the following code into the class for the form:
Private lvwColumnSorter As ListViewColumnSorter
- Paste the following code into the constructor of the form,
after the call to the InitializeComponent method:
' Create an instance of a ListView column sorter and assign it
' to the ListView control.
lvwColumnSorter = New ListViewColumnSorter()
Me.ListView1.ListViewItemSorter = lvwColumnSorter
- Paste the following code into the Load event of the form:
Dim columnheader As ColumnHeader ' Used for creating column headers.
Dim listviewitem As ListViewItem ' Used for creating ListView items.
' Make sure that the view is set to show details.
ListView1.View = View.Details
' Create some ListView items consisting of first and last names.
listviewitem = New ListViewItem("Mike")
listviewitem.SubItems.Add("Nash")
Me.ListView1.Items.Add(listviewitem)
listviewitem = New ListViewItem("Kim")
listviewitem.SubItems.Add("Abercrombie")
Me.ListView1.Items.Add(listviewitem)
listviewitem = New ListViewItem("Sunil")
listviewitem.SubItems.Add("Koduri")
Me.ListView1.Items.Add(listviewitem)
listviewitem = New ListViewItem("Birgit")
listviewitem.SubItems.Add("Seidl")
Me.ListView1.Items.Add(listviewitem)
' Create some column headers for the data.
columnheader = New ColumnHeader()
columnheader.Text = "First Name"
Me.ListView1.Columns.Add(columnheader)
columnheader = New ColumnHeader()
columnheader.Text = "Last Name"
Me.ListView1.Columns.Add(columnheader)
' Loop through and size each column header to fit the column header text.
For Each columnheader In Me.ListView1.Columns
columnheader.Width = -2
Next
- Paste the following code into the ColumnClick event for the ListView:
' Determine if the clicked column is already the column that is
' being sorted.
If (e.Column = lvwColumnSorter.SortColumn) Then
' Reverse the current sort direction for this column.
If (lvwColumnSorter.Order = SortOrder.Ascending) Then
lvwColumnSorter.Order = SortOrder.Descending
Else
lvwColumnSorter.Order = SortOrder.Ascending
End If
Else
' Set the column number that is to be sorted; default to ascending.
lvwColumnSorter.SortColumn = e.Column
lvwColumnSorter.Order = SortOrder.Ascending
End If
' Perform the sort with these new sort options.
Me.ListView1.Sort()
- On the Project menu, click Add Class to add a new class to the project.
- Replace all of the default code in the new class with the
following code:
Imports System.Collections
Imports System.Windows.Forms
Public Class ListViewColumnSorter
Implements System.Collections.IComparer
Private ColumnToSort As Integer
Private OrderOfSort As SortOrder
Private ObjectCompare As CaseInsensitiveComparer
Public Sub New()
' Initialize the column to '0'.
ColumnToSort = 0
' Initialize the sort order to 'none'.
OrderOfSort = SortOrder.None
' Initialize the CaseInsensitiveComparer object.
ObjectCompare = New CaseInsensitiveComparer()
End Sub
Public Function Compare(ByVal x As Object, ByVal y As Object) As Integer Implements IComparer.Compare
Dim compareResult As Integer
Dim listviewX As ListViewItem
Dim listviewY As ListViewItem
' Cast the objects to be compared to ListViewItem objects.
listviewX = CType(x, ListViewItem)
listviewY = CType(y, ListViewItem)
' Compare the two items.
compareResult = ObjectCompare.Compare(listviewX.SubItems(ColumnToSort).Text, listviewY.SubItems(ColumnToSort).Text)
' Calculate the correct return value based on the object
' comparison.
If (OrderOfSort = SortOrder.Ascending) Then
' Ascending sort is selected, return typical result of
' compare operation.
Return compareResult
ElseIf (OrderOfSort = SortOrder.Descending) Then
' Descending sort is selected, return negative result of
' compare operation.
Return (-compareResult)
Else
' Return '0' to indicate that they are equal.
Return 0
End If
End Function
Public Property SortColumn() As Integer
Set(ByVal Value As Integer)
ColumnToSort = Value
End Set
Get
Return ColumnToSort
End Get
End Property
Public Property Order() As SortOrder
Set(ByVal Value As SortOrder)
OrderOfSort = Value
End Set
Get
Return OrderOfSort
End Get
End Property
End Class
- Save, build, and then run the sample project.
- Click the various column headers in the ListView control. When you click the header, the contents of the ListView control are sorted in ascending order based on the column that
you click. When you click the same column header again, that column is sorted
in descending order.
back to the top