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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1214289/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 11:09:16  来源:igfitidea点击:

how do I sort Integers in a listview

c#winformslistview

提问by Brad

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

系统.Windows.Forms.ListView

采纳答案by Neil N

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 甚至你的列表视图控件:

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。

回答by Jimmy Chandra

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.

我会在数据源(模型)而不是视图中进行。在那里对它进行排序,它应该通过数据绑定在视图中更新它。

回答by Fredrik M?rk

You will need to create a class that implements the IComparerinterface (the non-generic one). In that class you read the Textproperty from the correct sub-item, convert it to int, and do the comparison:

您将需要创建一个实现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);
    }
}

Then you assign such a comparer to the ListViewItemSorter property and invoke the sort method of the ListView control:

然后将这样的比较器分配给 ListViewItemSorter 属性并调用 ListView 控件的排序方法:

// create a comparer for column index 1 and assign it to the control, and sort
myListView.ListViewItemSorter = new IntegerComparer(1);
myListView.Sort();

回答by Grammarian

If you are getting started with a ListView, your life will be much much easier if you use an ObjectListViewinstead. 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. For example, it automatically sorts ints so that '100' comes after '3' (DateTimes, bools, and everything else sorts correctly too).

如果您刚开始使用 ListView,如果您改用ObjectListView,您的生活会容易得多。ObjectListView 是一个围绕 .NET WinForms ListView 的开源包装器,它解决了所有这些恼人的小问题,这些小问题通常会使使用 ListView 变得如此令人沮丧。例如,它会自动对整数进行排序,以便“100”排在“3”之后(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 herefor some other people's opinions.

是的,我是作者——但这并不意味着我有偏见......好吧,也许确实如此:)在这里看看其他人的意见。

回答by VicF

I used Neil-N's class but changed the if statement to test the Type property instead of the Tag property. I set each column to Type Number (instead of Text) that had an integer value in it. Sort works great.

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

if (l1.ListView.Columns[Column].Type.ToString() == "Number")

回答by Martin.Martinsson

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

回答by YourFriend

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

排序前后的图像