Comment puis-je trier les colonnes d'entiers dans une liste de liste p>
C #, .NET 2.0, Winform P>
System.Windows.Forms.ListView P>
7 Réponses :
Je le ferais dans la source de données (modèle) au lieu de la vue. Triez-le là-bas et il devrait le mettre à jour dans la vue via la base de données. P>
Vous voulez dire trier la source de données, la table de données de mon instance, puis recharger la liste de liste une fois que jamais une colonne est cliquée?
Non, mauvaise pratique à recharger à chaque fois. Google "Soreur d'élément ListView" et il vous montrera comment trier par chaque colonne.
Oups ... ne savait pas que c'était pour le formulaire Windows. Je viens de supposer WPF.
Voici comment j'ai accompli de pouvoir trier sur plusieurs colonnes et pouvoir trier chaque colonne en tant que numéro ou en tant que texte.
Utilisez d'abord cette classe: P>
private void lvSeries_ColumnClick(object sender, ColumnClickEventArgs e)
{
Sorter s = (Sorter)lvSeries.ListViewItemSorter;
s.Column = e.Column;
if (s.Order == System.Windows.Forms.SortOrder.Ascending)
{
s.Order = System.Windows.Forms.SortOrder.Descending;
}
else
{
s.Order = System.Windows.Forms.SortOrder.Ascending;
}
lvSeries.Sort();
}
@Neil: Cela les trie comme texte par défaut. Par exemple. 100 vient avant 3. Cependant, vous pouvez trier l'INT correctement avec Personnalisé ListVieveviePorter.
J'ai suivi l'exemple à support.microsoft.com/kb/319401 mais il ne trie toujours pas Les entiers correctement.wront du texte, comment définissez-vous la colonne par défaut pour trier. Il trie juste bien sur la colonne 1 mais je ne trouve que la propriété de régler la colonne pour trier.
Geate!, Je viens d'utiliser de nombreuses pages qui affichent le nom de la colonne de grille comme 'id' b>. Donc, j'ai été changé si (l1.listview.columns [colonne] .tag.tostring () == "numérique") code> à if (l1.listview.columns [colonne] .. Text.toupper.indexof ("id")> -1 code>. C'est le travail. Merci pour la part!
Vous devrez créer une classe qui implémente le Icomarer code> interface (le non générique). Dans cette classe, vous avez lu la alors vous attribuez un tel comparateur à la propriété ListVievevemSorter et Invoquer la méthode de tri du contrôle ListView: P> Texte code> propriété à partir du bon sous-élément, convertissez-le sur INT, et faites la comparaison: // create a comparer for column index 1 and assign it to the control, and sort
myListView.ListViewItemSorter = new IntegerComparer(1);
myListView.Sort();
Certaines colonnes sont numériques d'autres sont du texte ... Devrais-je tester pour numériquement avant de tri?
J'ai effectué une fois un comparateur ListViewItem qui a examiné chaque paire d'éléments dans la méthode de comparaison, mais cela est devenu assez lent. Vous ferez mieux d'avoir des comparateurs distincts et de choisir celui à utiliser sur la base de la colonne en cours de tri, ou de la création d'une classe de comparateur où vous transmettez une valeur au constructeur indiquant si vous souhaitez effectuer une sorte de numéros, dates ou texte, puis passer dans la méthode de comparaison en fonction de cette valeur (qui était la solution que je suis allé dans ce cas).
Bonne idée. Mais j'ai créé une variable privée comme 'SortType' à l'intérieur de ma liste de comparaison de listeVoir la page.
Si vous commencez avec une liste de réception, votre vie sera beaucoup plus facile si vous utilisez un ObjectListView à la place. ObjectListView est une enveloppe open source autour de Winforms Winforms Listview et il résout tous ces petits problèmes gênants qui font normalement travailler avec une vision de liste si frustrante. Par exemple, il trie automatiquement des intens pour que '100' vient après '3' (DateTimes, bools et tout le reste trie correctement). P>
Sérieusement, vous ne voudrez plus jamais revenir à une liste plaine de vue après avoir utilisé une liste ObjetListView. p>
Oui, je suis l'auteur - mais ça ne veut pas dire que je suis biaisé ... Ok, bien peut-être que ça fait :) Regardez ici pour des opinions d'autres personnes. p>
J'ai utilisé la classe de Neil-N mais j'ai modifié la déclaration IF pour tester la propriété Type au lieu de la propriété Tag. J'ai défini chaque colonne sur le numéro de type (au lieu de texte) qui avait une valeur entière dedans. Trier fonctionne bien.
Je ne sais pas si vous avez laissé quelque chose, mais ColonneHeader n'a pas de propriété code> code>.
class ListViewAutoSorter : System.Collections.IComparer
{
private int Column = 0;
private System.Windows.Forms.SortOrder Order = SortOrder.Ascending;
public ListViewAutoSorter(int Column, SortOrder Order)
{
this.Column = Column;
this.Order = Order;
}
public int Compare(object x, object y) // IComparer Member
{
if (!(x is ListViewItem))
return (0);
if (!(y is ListViewItem))
return (0);
var l1 = (ListViewItem)x;
var l2 = (ListViewItem)y;
var value1 = 0.0;
var value2 = 0.0;
if (Double.TryParse(l1.SubItems[Column].Text, out value1) &&
Double.TryParse(l2.SubItems[Column].Text, out value2))
{
if (Order == SortOrder.Ascending)
{
return value1.CompareTo(value2);
}
else
{
return value2.CompareTo(value1);
}
}
else
{
var str1 = l1.SubItems[Column].Text;
var str2 = l2.SubItems[Column].Text;
if (Order == SortOrder.Ascending)
{
return str1.CompareTo(str2);
}
else
{
return str2.CompareTo(str1);
}
}
}
}
Public Class Form1
Private Sub btnSortListView_Click(sender As Object, e As EventArgs) Handles btnSortListView.Click
If btnSortListView.Text = "Sort Ascending" Then
ListViewGar.ListViewItemSorter = New IntegerComparer(1)
ListViewGar.Sort()
btnSortListView.Text = "Not Sort"
Else
ListViewGar.ListViewItemSorter = New IntegerComparer(0)
btnSortListView.Text = "Sort Ascending"
End If
End Sub
End Class
Public Class IntegerComparer
Implements System.Collections.IComparer
Private _colIndex As Integer
Public Sub New(ByVal colIndex As Integer)
MyBase.New
Me._colIndex = colIndex
End Sub
'Public Function Compare(ByVal x As Object, ByVal y As Object) As Integer
' Dim nx As Integer = Integer.Parse(CType(x, ListViewItem).SubItems(Me._colIndex).Text)
' Dim ny As Integer = Integer.Parse(CType(y, ListViewItem).SubItems(Me._colIndex).Text)
' Return nx.CompareTo(ny)
'End Function
Private Function IComparer_Compare(x As Object, y As Object) As Integer Implements IComparer.Compare
Dim nx As Integer = Integer.Parse(CType(x, ListViewItem).SubItems(Me._colIndex).Text)
Dim ny As Integer = Integer.Parse(CType(y,ListViewItem).SubItems(Me._colIndex).Text)
Dim colIndPlus As Integer = Me._colIndex
Do While nx.CompareTo(ny) = 0
colIndPlus = colIndPlus + 1
nx = Integer.Parse(CType(x, ListViewItem).SubItems(colIndPlus).Text)
ny = Integer.Parse(CType(y, ListViewItem).SubItems(colIndPlus).Text)
Loop
Return nx.CompareTo(ny)
End Function
End Class
image before and after sort
La question concerne le C # ... mais la plupart peuvent probablement traduire.
Asp.net? Formulaires Windows?
J'ai édité ma réponse pour inclure un exemple complet, qui peut trier comme texte et numérique