简体   繁体   English

如何在列表视图中对整数进行排序

[英]how do I sort Integers in a listview

How do I sort columns of integers in a ListView 如何在ListView中对整数列进行排序

c#, .net 2.0, Winform c#,。net 2.0,Winform

System.Windows.Forms.ListView System.Windows.Forms.ListView

This is how I accomplished being able to sort on multiple columns, and being able to sort each column as a number, or as text. 这就是我如何完成对多列进行排序,并能够将每列作为数字或文本进行排序的方法。

First use this class: 首先使用这个类:

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

In your form's constructor, set the sorter like this: 在表单的构造函数中,将分类器设置为:

lvSeries.ListViewItemSorter = new Sorter();

Then handle the ColumnClick even of your listview control like this: 然后处理ColumnClick甚至是listview控件,如下所示:

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

This is all dependent on the Tag property of each column either being set to "Numeric" or not, so the sorter knows how to sort. 这完全取决于每列的Tag属性是否设置为“Numeric”,因此分拣机知道如何排序。

In the above example I cast the values as floats when numeric, you may want to change that to int. 在上面的例子中,我在数值时将值转换为浮点数,您可能希望将其更改为int。

If you are getting started with a ListView, your life will be much much easier if you use an ObjectListView instead. 如果您开始使用ListView,那么如果您使用ObjectListView ,您的生活将会轻松得多。 ObjectListView is an open source wrapper around .NET WinForms ListView, and it solves all these annoying little problems that normally make working with a ListView so frustrating. ObjectListView是一个围绕.NET WinForms ListView的开源包装器,它解决了所有这些烦人的小问题,这些问题通常使得使用ListView非常令人沮丧。 For example, it automatically sorts ints so that '100' comes after '3' (DateTimes, bools, and everything else sorts correctly too). 例如,它会自动对int进行排序,以便在'3'之后出现'100'(DateTimes,bools,以及其他所有内容也正确排序)。

Seriously, you will never want to go back to a plain ListView after using an ObjectListView. 说真的,在使用ObjectListView之后,你永远不会想要回到普通的ListView。

Yes, I am the author -- but that doesn't mean I'm biased... OK, well maybe it does :) Look here for some other people's opinions. 是的,我是作者 - 但这并不意味着我有偏见......好吧,也许它确实:)看看这里有其他人的意见。

You will need to create a class that implements the IComparer interface (the non-generic one). 您将需要创建一个实现IComparer接口的类(非泛型接口)。 In that class you read the Text property from the correct sub-item, convert it to int, and do the comparison: 在该类中,您从正确的子项读取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);
    }
}

Then you assign such a comparer to the ListViewItemSorter property and invoke the sort method of the ListView control: 然后将这样的比较器分配给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();

I'd do it in the data source (model) instead of the view. 我会在数据源(模型)而不是视图中执行此操作。 Sort it there and it should update it in the view through databinding. 在那里排序它应该通过数据绑定在视图中更新它。

I used Neil-N's class but changed the if statement to test the Type property instead of the Tag property. 我使用了Neil-N的类,但更改了if语句以测试Type属性而不是Tag属性。 I set each column to Type Number (instead of Text) that had an integer value in it. 我将每列设置为Type Number(而不是Text),其中包含整数值。 Sort works great. 排序很棒。

if (l1.ListView.Columns[Column].Type.ToString() == "Number")
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 排序之前和之后的图像

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM