Pour la deuxieme question je sais pas, mais pour la première j'ai la solution:
En fait, il te faut une classe "ListViewItemComparer" ou tu décideras comment faire ton tri.
La fonction Compare sert simplement à dire si la valeur 1 va avant ou apres la valeur 2 dans la liste: elle renvoie 1 ou -1.
Voila la mienne :
Public Class ListViewItemComparer
Implements IComparer
Private col As Integer
Private order As SortOrder
Public Sub New()
col = 0
order = SortOrder.Ascending
End Sub
Public Sub New(ByVal column As Integer, ByVal order As SortOrder)
col = column
Me.order = order
End Sub
Public Function Compare(ByVal x As Object, ByVal y As Object) As Integer Implements System.Collections.IComparer.Compare
Dim returnVal As Integer
Dim s1 As String
Try 'Pour éviter les plantages quand l'info 1 est vide
s1 = CType(x, ListViewItem).SubItems(col).Text 'info à comparer n°1
Catch ex As Exception
s1 = ""
End Try
Dim s2 As String
Try 'Pour éviter les plantages quand l'info 2 est vide
s2 = CType(y, ListViewItem).SubItems(col).Text 'info à comparer n°2
Catch ex As Exception
s2 = ""
End Try
Try
If s1.EndsWith(" €") And s2.EndsWith(" €") Then 'Cas des nombres avec " €" à la fin
Dim i As Single = CSng(s1.Substring(0, s1.Length - 2))
Dim j As Single = CSng(s2.Substring(0, s2.Length - 2)) If i > j Then returnVal 1 Else returnVal -1
ElseIf s1.EndsWith(" %") And s2.EndsWith(" %") Then 'Cas des nombres avec " %" à la fin
Dim i As Single = CSng(s1.Substring(0, s1.Length - 2))
Dim j As Single = CSng(s2.Substring(0, s2.Length - 2)) If i > j Then returnVal 1 Else returnVal -1
ElseIf s1.EndsWith(" %") Then 'Cas ou seule l'info 1 finit par "%"
returnVal = 1
ElseIf s2.EndsWith(" %") Then 'Cas ou seule l'info 2 finit par "%"
returnVal = -1
ElseIf (s1.IndexOf("/", s1.IndexOf("/") + 1) <> -1) And s2.IndexOf("/", s2.IndexOf("/") + 1) <> -1 Then 'Comparaison de deux dates
returnVal = DateTime.Compare(DateTime.Parse(s1), DateTime.Parse(s2))
ElseIf s1.IndexOf("20") <> -1 Then 'Comparaison des mois (Ex: Janvier 2004, Juillet 2003,...)
Dim i As Int16
Dim b1 As Boolean = False
Dim b2 As Boolean = False
For i = 1 To 12
If s1.IndexOf(Fcts.Maj_Initiale(MonthName(i))) <> -1 Then b1 = True
If s2.IndexOf(Fcts.Maj_Initiale(MonthName(i))) <> -1 Then b2 = True
Next i
If b1 And b2 Then
returnVal = DateTime.Compare(CDate(s1), CDate(s2))
Else
returnVal = [String].Compare(s1, s2)
End If
Else 'Comparaison en tant que chaines
returnVal = [String].Compare(s1, s2)
End If
Catch 'En cas de plantage, on compare en tant que chaines
returnVal = [String].Compare(s1, s2)
End Try
If order = SortOrder.Descending Then
returnVal *= -1
End If
Return returnVal
End Function
End Class
Si tu veux trier des nombres sans rien derriere, il te suffit de rajouter une ligne avec un test qui permet de dire que ce sont bien des nombres
If Estunnombre(s1) And Estunnombre(s2) then
Dim i As Single/integer = CSng(s1) ou Cint(s1)
Dim j As Single/integer = CSng(s2) ou Cint(s2) If i > j Then returnVal 1 Else returnVal -1
elseif la suite...
Ensuite, il te faut une fonction qui lance le tri:
Sub LV_tri(ByVal lv As ListView, ByVal col As Int16)
If col <> lv.Tag Then 'Si la colonne n'est pas triée
lv.Tag = col
lv.Sorting = SortOrder.Ascending
Else
If lv.Sorting = SortOrder.Ascending Then
lv.Sorting = SortOrder.Descending
Else
lv.Sorting = SortOrder.Ascending
End If
End If
lv.ListViewItemSorter = New ListViewItemComparer(col, lv.Sorting) 'C'est la qu'on fait appel à la procédure plus haut
End Sub
Attention, ma méthode utilise le tag de la listview pour savoir quelle a été la dernière colonne cliquée donc soit sur que tu utilise pas le tag pour faire autre chose.
Enfin, tu appelles cette fonction lors de l'évenement Malistview.columnclick:
Private Sub LV_solde_ColumnClick(ByVal sender As Object, ByVal e As System.Windows.Forms.ColumnClickEventArgs) Handles LV_solde.ColumnClick
Fcts.LV_tri(LV_solde, e.Column)
End Sub
Voila
@+