hay varias maneras pero una de las mejores es usar la interface llamada
IComparer. aca te paso la clase que usaba:
Public Class COrdenarListview
Implements IComparer
Private vIndiceColumna As Integer
Private vTipoOrden As SortOrder
Public Sub New(ByVal pIndiceColumna As Integer, ByVal pTipoOrden As SortOrder)
vIndiceColumna = pIndiceColumna
vTipoOrden = pTipoOrden
End Sub
Public Function Ordenar(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 <= vIndiceColumna Then
string_x = ""
Else
string_x = item_x.SubItems(vIndiceColumna).Text
End If
Dim string_y As String
If item_y.SubItems.Count <= vIndiceColumna Then
string_y = ""
Else
string_y = item_y.SubItems(vIndiceColumna).Text
End If
If vTipoOrden = 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
luego para usarla tenes que usar el evento
ColumnClick de esta forma:
Private Sub lv_ColumnClick(ByVal sender As Object, ByVal e As System.Windows.Forms.ColumnClickEventArgs) Handles lv.ColumnClick
Dim vIndiceColumna As ColumnHeader = lv.Columns(e.Column)
Dim vTipoOrden As System.Windows.Forms.SortOrder
If vColumnaOrden Is Nothing Then
vTipoOrden = SortOrder.Ascending
vOrden = SortOrder.Ascending
Else
If vIndiceColumna.Equals(vColumnaOrden) Then
If vOrden = SortOrder.Ascending Then
vTipoOrden = SortOrder.Descending
vOrden = SortOrder.Descending
Else
vTipoOrden = SortOrder.Ascending
vOrden = SortOrder.Ascending
End If
Else
vTipoOrden = SortOrder.Ascending
vOrden = SortOrder.Ascending
End If
End If
vColumnaOrden = vIndiceColumna
lv.ListViewItemSorter = New COrdenarListview(e.Column, vTipoOrden)
lv.Sort()
End Sub
esta lo que hace es que te "detecta" por asi decirlo, el tipo de datos de la columna y te lo ordena dependiendo ese tipo de dato, por ejemplo si tenes numeros te lo ordena como numero y no como string, te detecta las fechas y los strings comunes, y tiene los 2 metodos ascendente y descendente.
digo "usaba", porque desde hace rato ya en .NET uso el ObjectListview, es lejos el mejor control creado para .NET, el cual te facilita todo, es mil veces mejor que el Listview de .NET, y tambien te hace todo automatico el tema del ordenamiento. te ahorras todo estos temas de ensuciar el codigo con cada cosita extra que uno necesita hacer.
saludos.