Gewusst wie: Sortieren von ListView-Elementen
Aktualisiert: November 2007
In .NET Compact Framework wird die Sort-Methode für ListView nicht unterstützt, trotzdem können Sie Elemente jedoch mithilfe der IComparer-Schnittstelle sortieren und die Sort-Methode für ArrayList verwenden.
In der folgenden Tabelle werden drei Klassen definiert:
Klasse |
Beschreibung |
---|---|
ColHeader |
Diese von der ColumnHeader-Klasse abgeleitete Klasse wird verwendet, um dem ListView-Steuerelement Spalten hinzuzufügen und die Spalte, auf die geklickt wurde, zu sortieren. Sie umfasst die ascending-Eigenschaft, mit der die Sortierreihenfolge angegeben wird: true gibt die aufsteigende und false die absteigende Sortierung an. |
SortWrapper |
Wenn auf eine Spalte geklickt wird, wird für jedes ListItem eine Instanz dieser Klasse erstellt und einer ArrayList hinzugefügt. Jedes eingebundene Element umfasst eine Eigenschaft, die den Index der Spalte, auf die geklickt wurde, enthält. Diese Klasse enthält die SortComparer-Klasse. |
SortComparer |
Innerhalb der SortWrapper-Klasse definiert diese Klasse eine Implementierung der IComparer-Schnittstelle, deren Compare-Methode je zwei Objekte vergleicht, während die ArrayList sortiert wird. |
Der Ereignishandler für das ColumnClick-Ereignis führt den Sortiervorgang wie folgt aus:
Es wird eine Instanz der ColHeader-Klasse erstellt, um zu ermitteln, auf welche Spalte geklickt wurde.
Die ascending-Eigenschaft des ColHeader-Objekts wird festgelegt, um die entgegengesetzte Sortierreihenfolge festzulegen.
Die Anzahl der Elemente in der Liste wird abgerufen.
Das Neuaufbauen der Anzeige während des Sortiervorgangs wird mit der BeginUpdate-Methode deaktiviert.
Für jedes ListView-Element wird SortWrapper zu einer ArrayList hinzugefügt.
Die Elemente in der ArrayList werden mithilfe einer neuen Instanz der SortComparer-Klasse sortiert, deren Implementierung der IComparer-Schnittstelle die Sortierlogik in der Compare-Methode enthält.
Die Elemente aus dem ListView-Steuerelement werden gelöscht, und das Steuerelement wird mit den sortierten Elementen aus der ArrayList erneut aufgefüllt.
Das Neuaufbauen der Anzeige wird mit der EndUpdate-Methode aktiviert.
Beachten Sie, dass mit der Sort-Methode für ArrayList eine instabile Sortierung durchgeführt wird, d. h., bei zwei gleichen Elementen wird deren Reihenfolge möglicherweise nicht beibehalten. Bei einer stabilen Sortierung wird hingegen die Reihenfolge von gleichen Elementen beibehalten.
So erstellen Sie die Anwendung
Fügen Sie die SortWrapper-Klasse dem Projekt hinzu, das auch die SortComparer-Klasse enthält.
' An instance of the SortWrapper class is created for ' each item and added to the ArrayList for sorting. Public Class SortWrapper Friend sortItem As ListViewItem Friend sortColumn As Integer ' A SortWrapper requires the item and the index of the clicked column. Public Sub New(ByVal Item As ListViewItem, ByVal iColumn As Integer) sortItem = Item sortColumn = iColumn End Sub ' Text property for getting the text of an item. Public ReadOnly Property [Text]() As String Get Return sortItem.SubItems(sortColumn).Text End Get End Property ' Implementation of the IComparer ' interface for sorting ArrayList items. Public Class SortComparer Implements IComparer Private ascending As Boolean ' Constructor requires the sort order; ' true if ascending, otherwise descending. Public Sub New(ByVal asc As Boolean) Me.ascending = asc End Sub ' Implemnentation of the IComparer:Compare ' method for comparing two objects. Public Function [Compare](ByVal x As Object, ByVal y As Object) As Integer Implements IComparer.Compare Dim xItem As SortWrapper = CType(x, SortWrapper) Dim yItem As SortWrapper = CType(y, SortWrapper) Dim xText As String = xItem.sortItem.SubItems(xItem.sortColumn).Text Dim yText As String = yItem.sortItem.SubItems(yItem.sortColumn).Text Return xText.CompareTo(yText) * IIf(Me.ascending, 1, -1) End Function End Class End Class
// An instance of the SortWrapper class is created for // each item and added to the ArrayList for sorting. public class SortWrapper { internal ListViewItem sortItem; internal int sortColumn; // A SortWrapper requires the item and the index of the clicked column. public SortWrapper (ListViewItem Item, int iColumn) { sortItem = Item; sortColumn = iColumn; } // Text property for getting the text of an item. public string Text { get { return sortItem.SubItems[sortColumn].Text; } } // Implementation of the IComparer // interface for sorting ArrayList items. public class SortComparer : IComparer { bool ascending; // Constructor requires the sort order; // true if ascending, otherwise descending. public SortComparer(bool asc) { this.ascending = asc; } // Implemnentation of the IComparer:Compare // method for comparing two objects. public int Compare(object x, object y) { SortWrapper xItem = (SortWrapper) x; SortWrapper yItem = (SortWrapper) y; string xText = xItem.sortItem.SubItems[xItem.sortColumn].Text; string yText = yItem.sortItem.SubItems[yItem.sortColumn].Text; return xText.CompareTo(yText) * (this.ascending ? 1 : -1); } } }
Fügen Sie dem Projekt die ColHeader-Klasse hinzu.
' The ColHeader class is a ColumnHeader object with an ' added property for determining an ascending or descending sort. ' True specifies an ascending order, false specifies a descending order. Public Class ColHeader Inherits ColumnHeader Public ascending As Boolean Public Sub New(ByVal [text] As String, ByVal width As Integer, ByVal align As HorizontalAlignment, ByVal asc As Boolean) Me.Text = [text] Me.Width = width Me.TextAlign = align Me.ascending = asc End Sub End Class
// The ColHeader class is a ColumnHeader object with an // added property for determining an ascending or descending sort. // True specifies an ascending order, false specifies a descending order. public class ColHeader : ColumnHeader { public bool ascending; public ColHeader(string text, int width, HorizontalAlignment align, bool asc) { this.Text = text; this.Width = width; this.TextAlign = align; this.ascending = asc; } }
Fügen Sie mit der ColHeader-Klasse Spalten hinzu, und fügen Sie ListView-Elemente hinzu.
' Set to Details view. Me.listView1.View = View.Details ' Add columns using the ColHeader class. The fourth ' parameter specifies true for an ascending sort order. listView1.Columns.Add(New ColHeader("Name", 110, HorizontalAlignment.Left, True)) listView1.Columns.Add(New ColHeader("Region", 50, HorizontalAlignment.Left, True)) listView1.Columns.Add(New ColHeader("Sales", 70, HorizontalAlignment.Left, True)) ' Add the data. listView1.Items.Add(New ListViewItem(New String() {"Archer, Karen", "4", "0521.28"})) listView1.Items.Add(New ListViewItem(New String() {"Benson, Max", "8", "0828.54"})) listView1.Items.Add(New ListViewItem(New String() {"Bezio, Marin", "3", "0535.22"})) listView1.Items.Add(New ListViewItem(New String() {"Higa, Sidney", "2", "0987.50"})) listView1.Items.Add(New ListViewItem(New String() {"Martin, Linda", "6", "1122.12"})) listView1.Items.Add(New ListViewItem(New String() {"Nash, Mike", "7", "1030.11"})) listView1.Items.Add(New ListViewItem(New String() {"Sanchez, Ken", "1", "0958.78"})) listView1.Items.Add(New ListViewItem(New String() {"Smith, Ben", "5", "0763.25"})) ' Connect the ListView.ColumnClick event to the ColumnClick event handler. AddHandler Me.listView1.ColumnClick, AddressOf listView1_ColumnClick
this.listView1.View = View.Details; // Add columns using the ColHeader class. The fourth // parameter specifies true for an ascending sort order. listView1.Columns.Add(new ColHeader("Name", 110, HorizontalAlignment.Left, true)); listView1.Columns.Add(new ColHeader("Region", 50, HorizontalAlignment.Left, true)); listView1.Columns.Add(new ColHeader("Sales", 70, HorizontalAlignment.Left, true)); // Add the data. listView1.Items.Add(new ListViewItem(new string[] {"Archer, Karen","4","0521.28"})); listView1.Items.Add(new ListViewItem(new string[] {"Benson, Max","8","0828.54"})); listView1.Items.Add(new ListViewItem(new string[] {"Bezio, Marin","3","0535.22"})); listView1.Items.Add(new ListViewItem(new string[] {"Higa, Sidney","2","0987.50"})); listView1.Items.Add(new ListViewItem(new string[] {"Martin, Linda","6","1122.12"})); listView1.Items.Add(new ListViewItem(new string[] {"Nash, Mike","7","1030.11"})); listView1.Items.Add(new ListViewItem(new string[] {"Sanchez, Ken","1","0958.78"})); listView1.Items.Add(new ListViewItem(new string[] {"Smith, Ben","5","0763.25"})); // Connect the ListView.ColumnClick event to the ColumnClick event handler. this.listView1.ColumnClick += new ColumnClickEventHandler(listView1_ColumnClick);
Fügen Sie Code hinzu, um die Sortierung auszuführen.
Private Sub listView1_ColumnClick(ByVal sender As Object, ByVal e As ColumnClickEventArgs) ' Create an instance of the ColHeader class. Dim clickedCol As ColHeader = CType(Me.listView1.Columns(e.Column), ColHeader) ' Set the ascending property to sort in the opposite order. clickedCol.ascending = Not clickedCol.ascending ' Get the number of items in the list. Dim numItems As Integer = Me.listView1.Items.Count ' Turn off display while data is repoplulated. Me.listView1.BeginUpdate() ' Populate an ArrayList with a SortWrapper of each list item. Dim SortArray As New ArrayList Dim i As Integer For i = 0 To numItems - 1 SortArray.Add(New SortWrapper(Me.listView1.Items(i), e.Column)) Next i ' Sort the elements in the ArrayList using a new instance of the SortComparer ' class. The parameters are the starting index, the length of the range to sort, ' and the IComparer implementation to use for comparing elements. Note that ' the IComparer implementation (SortComparer) requires the sort ' direction for its constructor; true if ascending, othwise false. SortArray.Sort(0, SortArray.Count, New SortWrapper.SortComparer(clickedCol.ascending)) ' Clear the list, and repopulate with the sorted items. Me.listView1.Items.Clear() Dim z As Integer For z = 0 To numItems - 1 Me.listView1.Items.Add(CType(SortArray(z), SortWrapper).sortItem) Next z ' Turn display back on. Me.listView1.EndUpdate() End Sub
private void listView1_ColumnClick(object sender, ColumnClickEventArgs e) { // Create an instance of the ColHeader class. ColHeader clickedCol = (ColHeader)this.listView1.Columns[e.Column]; // Set the ascending property to sort in the opposite order. clickedCol.ascending = !clickedCol.ascending; // Get the number of items in the list. int numItems = this.listView1.Items.Count; // Turn off display while data is repoplulated. this.listView1.BeginUpdate(); // Populate an ArrayList with a SortWrapper of each list item. ArrayList SortArray = new ArrayList(); for (int i = 0; i < numItems; i++) { SortArray.Add(new SortWrapper(this.listView1.Items[i], e.Column)); } // Sort the elements in the ArrayList using a new instance of the SortComparer // class. The parameters are the starting index, the length of the range to sort, // and the IComparer implementation to use for comparing elements. Note that // the IComparer implementation (SortComparer) requires the sort // direction for its constructor; true if ascending, othwise false. SortArray.Sort(0, SortArray.Count, new SortWrapper.SortComparer(clickedCol.ascending)); // Clear the list, and repopulate with the sorted items. this.listView1.Items.Clear(); for (int i = 0; i < numItems; i++) this.listView1.Items.Add(((SortWrapper)SortArray[i]).sortItem); // Turn display back on. this.listView1.EndUpdate(); }
Kompilieren des Codes
Für dieses Beispiel sind Verweise auf die folgenden Namespaces erforderlich:
Siehe auch
Konzepte
Entwickeln benutzerdefinierter Steuerelemente
Gewusst-wie-Themen für .NET Compact Framework