【发布时间】:2010-11-15 21:41:22
【问题描述】:
如何对 ListView 中的整数列进行排序
c#、.net 2.0、Winform
System.Windows.Forms.ListView
【问题讨论】:
-
ASP.NET ? Windows 窗体?
-
我编辑了我的答案以包含一个完整的示例,它可以作为文本和数字进行排序
如何对 ListView 中的整数列进行排序
c#、.net 2.0、Winform
System.Windows.Forms.ListView
【问题讨论】:
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
【讨论】:
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);
}
}
}
}
【讨论】:
我使用了 Neil-N 的类,但更改了 if 语句来测试 Type 属性而不是 Tag 属性。我将每一列设置为类型编号(而不是文本),其中包含一个整数值。排序效果很好。
if (l1.ListView.Columns[Column].Type.ToString() == "Number")
【讨论】:
Type 属性。
如果您开始使用 ListView,如果您改用 ObjectListView,您的生活会轻松得多。 ObjectListView 是一个围绕 .NET WinForms ListView 的开源包装器,它解决了所有这些烦人的小问题,这些问题通常使使用 ListView 如此令人沮丧。例如,它会自动对 int 进行排序,以便 '100' 在 '3' 之后(DateTimes、bools 和其他所有内容也都正确排序)。
说真的,在使用 ObjectListView 之后,您将永远不想回到普通的 ListView。
是的,我是作者——但这并不意味着我有偏见……好吧,也许确实如此:) 看看here 了解其他人的意见。
【讨论】:
这就是我实现对多列进行排序以及将每一列作为数字或文本排序的方式。
首先使用这个类:
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。
【讨论】:
if (l1.ListView.Columns[Column].Tag.ToString() == "Numeric") 更改为if (l1.ListView.Columns[Column]..Text.ToUpper.IndexOf("ID") > -1。那是工作。感谢分享!
您需要创建一个实现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();
【讨论】:
我会在数据源(模型)而不是视图中执行此操作。在那里对其进行排序,它应该通过数据绑定在视图中更新它。
【讨论】: