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