.net中的ListView列表控件默认只能实现按第一列排序的功能,而且只能按字符串排序。由于项目需要重写了一个控件。继承自ListVIew,实现了能按每个列排序的功能,而且可以为每一列指定排序方式(数字,字符串,时间)。
完整代码如下:
using System;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace UserControl
{
/// <summary>
/// UserControl1 的摘要说明。
/// </summary>
public class myListView : System.Windows.Forms.ListView
{
/// <summary>
/// 必需的设计器变量。
/// 控件说明:
/// 此控件使用一个数组来保存每一列的排序方式。
/// 使用时:当创建了控件的列后,要使用InitTypeList()函数来根据列数生成数组数据。默认值为0,按字符串排序
/// 当有特殊要求时,可以指定相应列所对应的排序值。如typeList[3] = 2;
/// </summary>
private System.ComponentModel.Container components = null;
[DllImport("User32")]
private static extern bool LockWindowUpdate(IntPtr hWndLock);
public ArrayList typeList; //存放每一列的排序方式 :0:字符串 1:数字 2:日期
public myListView()
{
// 该调用是 Windows.Forms 窗体设计器所必需的。
InitializeComponent();
// TODO: 在 InitComponent 调用后添加任何初始化
this.typeList = new ArrayList();
}
/// <summary>
/// 清理所有正在使用的资源。
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if( components != null )
components.Dispose();
}
base.Dispose( disposing );
}
new public void Clear()
{
base.Clear();
this.typeList.Clear();
}
public void InitTypeList()
{
this.typeList.Clear();
for(int i=0; i<this.Columns.Count; i++)
{
this.typeList.Add(0); //初始化数组
}
}
#region 组件设计器生成的代码
/// <summary>
/// 设计器支持所需的方法 - 不要使用代码编辑器
/// 修改此方法的内容。
/// </summary>
private void InitializeComponent()
{
components = new System.ComponentModel.Container();
}
#endregion
protected override void OnColumnClick(ColumnClickEventArgs e)
{
base.OnColumnClick (e);
LockWindowUpdate(this.Handle);
this.BeginUpdate();
ColumnSort columnsort = new ColumnSort(e.Column);
columnsort.iSortTye = (int)this.typeList[e.Column];
columnsort.bAscending = (this.Sorting == SortOrder.Ascending);
if (columnsort.bAscending)
{
this.Sorting = SortOrder.Descending;
}
else
{
this.Sorting = SortOrder.Ascending;
}
this.ListViewItemSorter = columnsort;
this.Sort();
this.EndUpdate();
LockWindowUpdate(IntPtr.Zero);
}
protected override void OnLeave(EventArgs e)
{
base.OnLeave (e);
}
new public void Dispose()
{
base.Dispose();
this.typeList.Clear();
this.typeList = null;
}
public class ColumnSort:IComparer
{
private int columnNum = 0;
public bool bAscending = true;
public int iSortTye = 0; //排序方式:0:按字符串排序 1:按数字 2:按日期
double iRes = 0.0;
DateTime dTime1;
DateTime dTime2;
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)
{
if(
(listItemA.SubItems[columnNum].Text == null ||
listItemA.SubItems[columnNum].Text.Trim() == String.Empty) &&
(listItemB.SubItems[columnNum].Text ==null ||
listItemB.SubItems[columnNum].Text.Trim() ==String.Empty) )
return 0;
if(
(listItemA.SubItems[columnNum].Text == null ||
listItemA.SubItems[columnNum].Text.Trim() == String.Empty) &&
listItemB.SubItems[columnNum].Text != null)
return -1;
if(listItemA.SubItems[columnNum].Text
!= null && (listItemB.SubItems[columnNum].Text ==null ||
listItemB.SubItems[columnNum].Text.Trim() ==String.Empty) )
return 1;
if(this.iSortTye == 1)
{ //按数字
iRes = double.Parse(listItemA.SubItems[columnNum].Text) - double.Parse( listItemB.SubItems[columnNum].Text);
if(iRes < 0.0)
return -1;
else if(iRes > 0.0)
return 1;
else return 0;
}
else
if(this.iSortTye == 2)
{ //按日期
try
{
dTime1 = System.DateTime.Parse(listItemA.SubItems[columnNum].Text);
}
catch
{
dTime1 = new DateTime(1800,1,1,1,0,0,0);
}
try
{
dTime2 = System.DateTime.Parse(listItemB.SubItems[columnNum].Text);
}
catch
{
dTime2 = new DateTime(1800,1,1,1,0,0,0);
}
return System.DateTime.Compare(dTime1,dTime2);
//return
System.DateTime.Compare(System.DateTime.Parse(listItemA.SubItems[columnNum].Text),
System.DateTime.Parse(listItemB.SubItems[columnNum].Text));
}
else
{
return String.Compare(listItemA.SubItems[columnNum].Text,listItemB.SubItems[columnNum].Text);
}
}
else
{
if(listItemA.SubItems[columnNum].Text == null && listItemB.SubItems[columnNum].Text == null)
return 0;
if(listItemA.SubItems[columnNum].Text == null && listItemB.SubItems[columnNum].Text != null)
return 1;
if(listItemA.SubItems[columnNum].Text != null && listItemB.SubItems[columnNum].Text == null)
return -1;
//
if(this.iSortTye == 1)
{
iRes = double.Parse(listItemA.SubItems[columnNum].Text) - double.Parse( listItemB.SubItems[columnNum].Text);
if(iRes < 0.0)
return 1;
else if(iRes > 0.0)
return -1;
else return 0;
}
else if(this.iSortTye == 2)
{
try
{
dTime1 = System.DateTime.Parse(listItemA.SubItems[columnNum].Text);
}
catch
{
dTime1 = new DateTime(1800,1,1,1,0,0,0);
}
try
{
dTime2 = System.DateTime.Parse(listItemB.SubItems[columnNum].Text);
}
catch
{
dTime2 = new DateTime(1800,1,1,1,0,0,0);
}
return -1 * System.DateTime.Compare(dTime1,dTime2);
// return
-1 *
System.DateTime.Compare(System.DateTime.Parse(listItemA.SubItems[columnNum].Text),
System.DateTime.Parse(listItemB.SubItems[columnNum].Text));
}
else
{
return -1 * String.Compare(listItemA.SubItems[columnNum].Text,listItemB.SubItems[columnNum].Text);
}
}
}
}
}
}
使用示例:
第一次使用时都不要忘记初始化
this.listView_clerk.InitTypeList();this.listView_clerk.typeList[9] = 2;//为第10列指定排序方式为日期
this.listView_clerk.typeList[10] = 1;//排序方式为数字,其它列默认为按字符串排序