代码之家  ›  专栏  ›  技术社区  ›  Brad

如何对ListView中的整数排序

  •  6
  • Brad  · 技术社区  · 17 年前

    如何对ListView中的整数列进行排序

    C,.NET 2.0,WinForm

    系统.windows.forms.listview

    6 回复  |  直到 11 年前
        1
  •  19
  •   Neil N HLGEM    17 年前

    这就是我如何实现对多个列进行排序,以及将每个列作为数字或文本进行排序的方法。

    首先使用这个类:

    class Sorter : System.Collections.IComparer
    {
        public int Column = 0;
        public System.Windows.Forms.SortOrder Order = SortOrder.Ascending;
        public int Compare(object x, object y) // IComparer Member
        {
            if (!(x is ListViewItem))
                return (0);
            if (!(y is ListViewItem))
                return (0);
    
            ListViewItem l1 = (ListViewItem)x;
            ListViewItem l2 = (ListViewItem)y;
    
            if (l1.ListView.Columns[Column].Tag == null)
            {
                l1.ListView.Columns[Column].Tag = "Text";
            }
    
            if (l1.ListView.Columns[Column].Tag.ToString() == "Numeric")
            {
                float fl1 = float.Parse(l1.SubItems[Column].Text);
                float fl2 = float.Parse(l2.SubItems[Column].Text);
    
                if (Order == SortOrder.Ascending)
                {
                    return fl1.CompareTo(fl2);
                }
                else
                {
                    return fl2.CompareTo(fl1);
                }
            }
            else
            {
                string str1 = l1.SubItems[Column].Text;
                string str2 = l2.SubItems[Column].Text;
    
                if (Order == SortOrder.Ascending)
                {
                    return str1.CompareTo(str2);
                }
                else
                {
                    return str2.CompareTo(str1);
                }
            }
        }
    }
    

    在窗体的构造函数中,按如下方式设置排序器:

    lvSeries.ListViewItemSorter = new Sorter();
    

    然后像这样处理ListView控件的ColumnClick:

    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();
        }
    

    这都依赖于每列的标记属性,或者设置为“数字”或者不设置为“数字”,因此排序器知道如何排序。

    在上面的示例中,我将值强制转换为浮点数,您可能希望将其更改为int。

        2
  •  5
  •   Grammarian    17 年前

    如果您开始使用ListView,那么使用 ObjectListView 相反。ObjectListView是一个围绕.NET WinForms ListView的开放源代码包装器,它解决了所有这些让使用ListView变得如此令人沮丧的小问题。例如,它会自动对int排序,使“100”在“3”之后(日期时间、bools和其他所有内容也会正确排序)。

    说真的,在使用ObjectListView之后,您将永远不希望返回到普通的ListView。

    是的,我是作者——但这并不意味着我有偏见……好吧,也许是这样的:)看 here 其他人的意见。

        3
  •  3
  •   Fredrik Mörk    17 年前

    您需要创建一个实现 IComparer 接口(非通用接口)。在那节课上你读到了 Text 属性,将其转换为int,然后进行比较:

    public class IntegerComparer : IComparer
    {
        private int _colIndex;
        public IntegerComparer(int colIndex)
        {
            _colIndex = colIndex;
        }
        public int Compare(object x, object y)
        {
            int nx = int.Parse((x as ListViewItem).SubItems[_colIndex].Text);
            int ny = int.Parse((y as ListViewItem).SubItems[_colIndex].Text);
            return nx.CompareTo(ny);
        }
    }
    

    然后,将此类比较器分配给ListViewItemSorter属性,并调用ListView控件的Sort方法:

    // create a comparer for column index 1 and assign it to the control, and sort
    myListView.ListViewItemSorter = new IntegerComparer(1);
    myListView.Sort();
    
        4
  •  0
  •   Jimmy Chandra    17 年前

    我将在数据源(模型)中而不是视图中执行此操作。在那里排序,它应该通过数据绑定在视图中更新它。

        5
  •  0
  •   j0k gauthamp    14 年前

    我使用了Neil-N的类,但更改了if语句来测试类型属性而不是标记属性。我将每一列设置为包含整数值的数字(而不是文本)。排序效果很好。

    if (l1.ListView.Columns[Column].Type.ToString() == "Number")
    
        6
  •  0
  •   Martin.Martinsson    11 年前
    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);
                }
            }
        }
    }