如何:对 ListView 项排序

 

 

.NET Compact Framework 不支持 ListViewSort 方法,但您仍可以通过 IComparer 接口对项进行排序,并使用 ArrayListSort 方法。

下表定义了三个类。

说明

ColHeader

此类派生自 ColumnHeader 类,用于向 ListView 控件添加列并对已单击的列进行排序。它包含指定排序方向的 ascending 属性:true 表示升序,false 表示降序。

SortWrapper

单击某列时,将为每个 ListItem 创建此类的一个实例,并将这些实例添加到 ArrayList。每个包装项均包含一个属性,其中含有已单击列的索引。

此类包含 SortComparer 类。

SortComparer

SortWrapper 类中,此类用于定义 IComparer 接口的实现,该接口的 Compare 方法可以在对 ArrayList 进行排序时比较对象(每次两个)。

ColumnClick 事件的事件处理程序按照下面的过程执行排序操作:

  1. 创建 ColHeader 类的一个实例,以确定已单击的列。

  2. 设置 ColHeader 对象的升序属性以按相反方向排序。

  3. 获取列表中的项数。

  4. 使用 BeginUpdate 方法在排序过程中禁止绘制显示内容。

  5. 对于每个 ListView 项,将一个 SortWrapper 添加到 ArrayList

  6. 使用 SortComparer 类的新实例对 ArrayList 中的元素进行排序,该类的 IComparer 接口的实现在其 Compare 方法中包含排序逻辑。

  7. 清除项的 ListView 控件,然后使用 ArrayList 中的已排序项重新填充该控件。

  8. 使用 EndUpdate 方法允许绘制显示内容。

注意,ArrayList 中的 Sort 方法执行的是不稳定的排序,也就是说,如果两个元素相等,它们的顺序可能不会保持不变。相反,稳定排序则会保持相等元素的顺序。

创建应用程序

  1. SortWrapper 类添加到项目中,该项目还包含了 SortComparer 类。

    Visual Basic
    ' 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);
            }
        }
    }
    
  2. ColHeader 类添加到项目中。

    Visual Basic
    ' 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;
        }
    }
    
  3. 使用 ColHeader 类添加列,然后添加 ListView 项。

    Visual Basic
    ' 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);
    
  4. 添加代码以执行排序。

    Visual Basic
    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();
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值