【问题标题】:how do I sort Integers in a listview如何在列表视图中对整数进行排序
【发布时间】:2010-11-15 21:41:22
【问题描述】:

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

c#、.net 2.0、Winform

System.Windows.Forms.ListView

【问题讨论】:

  • ASP.NET ? Windows 窗体?
  • 我编辑了我的答案以包含一个完整的示例,它可以作为文本和数字进行排序

标签: c# winforms listview


【解决方案1】:
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

【讨论】:

  • 这个问题是关于 c#...但大多数可能会翻译。
【解决方案2】:
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);
            }
        }
    }
}

【讨论】:

    【解决方案3】:

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

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

    【讨论】:

    • 我不确定你是否遗漏了什么,但ColumnHeader 没有Type 属性。
    【解决方案4】:

    如果您开始使用 ListView,如果您改用 ObjectListView,您的生活会轻松得多。 ObjectListView 是一个围绕 .NET WinForms ListView 的开源包装器,它解决了所有这些烦人的小问题,这些问题通常使使用 ListView 如此令人沮丧。例如,它会自动对 int 进行排序,以便 '100' 在 '3' 之后(DateTimes、bools 和其他所有内容也都正确排序)。

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

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

    【讨论】:

      【解决方案5】:

      这就是我实现对多列进行排序以及将每一列作为数字或文本排序的方式。

      首先使用这个类:

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

      然后像这样处理列表视图控件的 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();
          }
      

      这完全取决于每列的 Tag 属性是否设置为“Numeric”,因此排序器知道如何排序。

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

      【讨论】:

      • @Neil:默认情况下将它们排序为文本。例如。 100 在 3 之前。但是,您可以使用自定义 ListViewItemSorter 正确排序 int。
      • 我按照support.microsoft.com/kb/319401 的示例进行了操作,但它仍然不能正确地对整数进行排序。Wrt 文本,你如何设置默认列进行排序。它在第 1 列上排序很好,但我找不到要为要排序的列设置的属性。
      • Geat!,我只是使用了许多显示 grid 列名的页面,例如 'ID'。因此,我将if (l1.ListView.Columns[Column].Tag.ToString() == "Numeric") 更改为if (l1.ListView.Columns[Column]..Text.ToUpper.IndexOf("ID") > -1。那是工作。感谢分享!
      【解决方案6】:

      您需要创建一个实现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 控件的排序方法:

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

      【讨论】:

      • 有些列是数字,有些是文本...我应该在排序之前测试数字吗?
      • 我曾经制作了一个 ListViewItem 比较器来检查 Compare 方法中的每个元素对,但这变得相当慢。您最好使用单独的比较器并根据要排序的列选择要使用的比较器,或者创建一个比较器类,在其中将值传递给构造函数,指示是否根据数字、日期或文本进行排序,然后根据该值切换 Compare 方法(这是我在这种情况下采用的解决方案)。
      • 好主意。但我在我的列表视图比较类中创建了一个私有变量,如“sortType”。
      【解决方案7】:

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

      【讨论】:

      • 您的意思是对我的实例中的数据源、数据表进行排序,然后在单击某个列时重新加载列表视图?
      • 不,每次重新加载都是不好的做法。谷歌“ListViewItemSorter”,它会告诉你如何按每列排序。
      • 糟糕...不知道这是针对 Windows 窗体的。我只是假设 wpf。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-09
      • 1970-01-01
      • 2013-08-13
      • 2011-11-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多