listview排序的问题

cononlove 2008-06-19 11:02:57
private void listView1_ColumnClick(object sender, ColumnClickEventArgs e)
{
ColumnSort columnsort = new ColumnSort(e.Column);
columnsort.bAscending = (listView1.Sorting == SortOrder.Ascending);
if (columnsort.bAscending)
{
listView1.Sorting = SortOrder.Descending;
}
else
{
listView1.Sorting = SortOrder.Ascending;
}
listView1.ListViewItemSorter = columnsort;
}
public class ColumnSort : IComparer
{
private int columnNum = 0;
public bool bAscending = true;
public ColumnSort(int column_to_sort)
{
columnNum = column_to_sort;
}

public int Compare(object a, object b)
{
System.Windows.Forms.ListViewItem
listItemA = (System.Windows.Forms.ListViewItem)a;
System.Windows.Forms.ListViewItem
listItemB = (System.Windows.Forms.ListViewItem)b;
if (bAscending)
{
return String.Compare(listItemA.SubItems[columnNum].ToString(), listItemB.SubItems[columnNum].ToString());
}
else
{
return -1 * String.Compare(listItemA.SubItems[columnNum].ToString(), listItemB.SubItems[columnNum].ToString());
}
}
}

这段代码是百度搜到的关于listview排序的,但是我不太懂这段代码,而且发现在程序运行中经常出现bug,敬请高手指教!
...全文
172 18 打赏 收藏 转发到动态 举报
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
Houkey 2008-10-03
  • 打赏
  • 举报
回复
mark
wzuomin 2008-06-19
  • 打赏
  • 举报
回复
刚才自动转换的C#代码有问题,不能运行。
下面这个是可以运行的


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace WindowsApplication2
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

private void Form1_Load(object sender, System.EventArgs e)
{
for (int i = 0; i <= 10; i++)
{
ListViewItem item = new ListViewItem("Item" + i.ToString());
item.SubItems.Add("TestItem");
this.listView1.Items.Add(item);
}
}

private void ListView_ColumnClick(object sender, System.Windows.Forms.ColumnClickEventArgs e)
{
this .listView1 .ListViewItemSorter = new ListViewItemComparer(e.Column);
this.listView1.Sort();
}
public class ListViewItemComparer : System.Collections.IComparer
{
private int col;
public bool bAscending = true ; //用于设置升序或降序

public ListViewItemComparer()
{
col = 0;
}

public ListViewItemComparer(int column)
{
col = column;
}

public int Compare(object x, object y)
{
if (bAscending )
return String.Compare(((ListViewItem)x).SubItems[col].Text, ((ListViewItem)y).SubItems[col].Text);
else
return -1 * String.Compare(((ListViewItem)x).SubItems[col].Text, ((ListViewItem)y).SubItems[col].Text);
}
}
}
}
cononlove 2008-06-19
  • 打赏
  • 举报
回复
错误提示是这样的:
InvalidArgument=“4”的值对于“index”无效。
参数名: index
不明白是什么意思...
zhnzzy 2008-06-19
  • 打赏
  • 举报
回复
if (columnsort.bAscending)
{
listView1.Sorting = SortOrder.Descending; //降序
}
else
{
listView1.Sorting = SortOrder.Ascending; //升序
}
wzuomin 2008-06-19
  • 打赏
  • 举报
回复
自动转成的c#代码如下(没测试,呵呵)

private void ListView_ColumnClick(object sender, System.Windows.Forms.ColumnClickEventArgs e)
{
ListView.ListViewItemSorter = new ListViewItemComparer(e.Column);
ListView.Sort();
}
class ListViewItemComparer : IComparer
{


private int col;

public ListViewItemComparer()
{
col = 0;
}

public ListViewItemComparer(int column)
{
col = column;
}

public int IComparer.Compare(object x, object y)
{
return String.Compare(((ListViewItem)x).SubItems(col).Text, ((ListViewItem)y).SubItems(col).Text);
}
}
wzuomin 2008-06-19
  • 打赏
  • 举报
回复
我有段代码是这么用的,lz可以试试看。


Private Sub ListView_ColumnClick(ByVal sender As Object, ByVal e As System.Windows.Forms.ColumnClickEventArgs) Handles ListView.ColumnClick
ListView.ListViewItemSorter = New ListViewItemComparer(e.Column)
ListView.Sort()
End Sub

Class ListViewItemComparer
Implements IComparer

Private col As Integer

Public Sub New()
col = 0
End Sub

Public Sub New(ByVal column As Integer)
col = column
End Sub

Public Function Compare(ByVal x As Object, ByVal y As Object) As Integer Implements IComparer.Compare
Return [String].Compare(CType(x, ListViewItem).SubItems(col).Text, CType(y, ListViewItem).SubItems(col).Text)
End Function
End Class
net0003 2008-06-19
  • 打赏
  • 举报
回复




我有个笨方法

获得列号,也就是SubItems[i]的i的值,在用for循环CompareTo SubItems[i] 和SubItems[i+1]应该就行了
cononlove 2008-06-19
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 net0003 的回复:]
就是当你点击哪一列的时候 就根据这列进行排序...


这么多贴,问你下,你要根据什么排序,第一列,第二列,还是什么,说明白了就好做了
[/Quote]
net0003 2008-06-19
  • 打赏
  • 举报
回复



这么多贴,问你下,你要根据什么排序,第一列,第二列,还是什么,说明白了就好做了
wzuomin 2008-06-19
  • 打赏
  • 举报
回复
[Quote=引用 16 楼 cononlove 的回复:]
多谢wzuomin
已经实现了排序,但是还有个小问题,就是排序时是按照逐个字符去比较大小的,比如说1,11,12,2,22,3,4,5 这几个数是这样排列的
1
11
12
2
22
3
4
5

如果我想按照
1
2
3
4
5
11
12
22
来排列该怎么做呢?
再次感谢!
[/Quote]

修改 Compare 中的两者比较方法即可。
cononlove 2008-06-19
  • 打赏
  • 举报
回复
多谢wzuomin
已经实现了排序,但是还有个小问题,就是排序时是按照逐个字符去比较大小的,比如说1,11,12,2,22,3,4,5 这几个数是这样排列的
1
11
12
2
22
3
4
5

如果我想按照
1
2
3
4
5
11
12
22
来排列该怎么做呢?
再次感谢!
xiaoqiuwyh 2008-06-19
  • 打赏
  • 举报
回复
根据你自己的程序中实际的名称来写,参数名index指的是一个索引值,也就是下标.
cononlove 2008-06-19
  • 打赏
  • 举报
回复
ListView_ColumnClick是不是改写成listView1_ColumnClick啊?
要不然提示有错啊...
wzuomin 2008-06-19
  • 打赏
  • 举报
回复

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace WindowsApplication2
{
public partial class Form1 : Form
{
private SortOrder sort = SortOrder.Ascending;

public Form1()
{
InitializeComponent();
}

private void Form1_Load(object sender, System.EventArgs e)
{
ListView ListView1 = new ListView();
ListView1.ColumnClick += ListView_ColumnClick;
ListView1.View = View.Details;
ListView1.Dock = DockStyle.Fill;
ListView1.Columns.Add("Column1");
ListView1.Columns.Add("Column2");

for (int i = 0; i <= 100; i++)
{
ListViewItem item = new ListViewItem("Item"+i.ToString ());
item.SubItems.Add("TestItem" + i.ToString());
ListView1.Items.Add(item);
}
this.Controls.Add(ListView1);
}

private void ListView_ColumnClick(object sender, System.Windows.Forms.ColumnClickEventArgs e)
{
if (sort == SortOrder.Ascending)
{
((ListView)sender).ListViewItemSorter = new ListViewItemComparer(e.Column, SortOrder.Ascending);
sort = SortOrder.Descending;
}
else
{
((ListView)sender).ListViewItemSorter = new ListViewItemComparer(e.Column, SortOrder.Descending);
sort = SortOrder.Ascending;
}

((ListView)sender).Sort();
}

public class ListViewItemComparer : System.Collections.IComparer
{

private int col;
public SortOrder sortOrder = SortOrder.Ascending;

public ListViewItemComparer()
{
col = 0;
}

public ListViewItemComparer(int column, SortOrder sort)
{
col = column;
sortOrder = sort;
}

public int Compare(object x, object y)
{
if (sortOrder == System.Windows.Forms.SortOrder.Ascending)
{
return String.Compare(((ListViewItem)x).SubItems[col].Text, ((ListViewItem)y).SubItems[col].Text);
}
else if (sortOrder == System.Windows.Forms.SortOrder.Descending)
{
return -1 * String.Compare(((ListViewItem)x).SubItems[col].Text, ((ListViewItem)y).SubItems[col].Text);
}
else
{
return 0;
}
}
}

}
}



这样再点击列标题看看是不是排序改变了呢?
wzuomin 2008-06-19
  • 打赏
  • 举报
回复
这是完整测试代码如下


Public Class Form1

Private sort As SortOrder = SortOrder.Ascending

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim ListView1 As New ListView
AddHandler ListView1.ColumnClick, AddressOf ListView_ColumnClick
ListView1.View = View.Details
ListView1.Dock = DockStyle.Fill
ListView1.Columns.Add("Column1")
ListView1.Columns.Add("Column2")

Dim rnd As New Random
For i As Integer = 0 To 100
Dim item As New ListViewItem(rnd.Next.ToString)
item.SubItems.Add("TestItem" + i.ToString)
ListView1.Items.Add(item)
Next
Me.Controls.Add(ListView1)
End Sub

Private Sub ListView_ColumnClick(ByVal sender As Object, ByVal e As System.Windows.Forms.ColumnClickEventArgs)
If sort = SortOrder.Ascending Then
CType(sender, ListView).ListViewItemSorter = New ListViewItemComparer(e.Column, SortOrder.Ascending)
sort = SortOrder.Descending
Else
CType(sender, ListView).ListViewItemSorter = New ListViewItemComparer(e.Column, SortOrder.Descending)
sort = SortOrder.Ascending
End If

CType(sender, ListView).Sort()
End Sub

Class ListViewItemComparer
Implements IComparer

Private col As Integer
Public sortOrder As SortOrder = SortOrder.Ascending

Public Sub New()
col = 0
End Sub

Public Sub New(ByVal column As Integer, ByVal sort As SortOrder)
col = column
sortOrder = sort
End Sub

Public Function Compare(ByVal x As Object, ByVal y As Object) As Integer Implements IComparer.Compare
If sortOrder = Windows.Forms.SortOrder.Ascending Then
Return [String].Compare(CType(x, ListViewItem).SubItems(col).Text, CType(y, ListViewItem).SubItems(col).Text)
ElseIf sortOrder = Windows.Forms.SortOrder.Descending Then
Return -1 * [String].Compare(CType(x, ListViewItem).SubItems(col).Text, CType(y, ListViewItem).SubItems(col).Text)
Else
Return 0
End If
End Function
End Class

End Class




wzuomin 2008-06-19
  • 打赏
  • 举报
回复
没反应?lz是不是没有绑定 ListView_ColumnClick 事件啊?
wzuomin 2008-06-19
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 cononlove 的回复:]
这个除了能生成10列外,没法排序啊? 能帮我解释下Compare(object x, object Y)这个函数吗,它返回的那个表达式是...?
谢谢!
引用 8 楼 wzuomin 的回复:
刚才自动转换的C#代码有问题,不能运行。
下面这个是可以运行的


C# code
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Window…
[/Quote]


用鼠标点击第一列可以排序的呀。
cononlove 2008-06-19
  • 打赏
  • 举报
回复
这个除了能生成10列外,没法排序啊? 能帮我解释下Compare(object x, object Y)这个函数吗,它返回的那个表达式是...?
谢谢!
[Quote=引用 8 楼 wzuomin 的回复:]
刚才自动转换的C#代码有问题,不能运行。
下面这个是可以运行的


C# code
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace WindowsApplication2
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent(…
[/Quote]

110,567

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧