.NET Framework 1.1中的ListView有一个AllowColumnReordered属性,设置为True后,用户可以通过鼠标拖动列来重新设置列的顺序(ViewStyle是Detail的时候才有效)。但是,ListView没有任何事件通知用户列的顺序被改变了。.NET Framework 2.0 中提供了事件ColumnReordered。我们可以通过扩展.NET Framework 1.1中的ListView来添加这个事件。
当用户拖动列的时候,会有一个BeginDrag的Windows通知消息,结束后,会有一个EndDrag 的Windows通知消息,因此,我们可以截获这个EndDrag的Windows通知消息,抛出ColumnReordered事件。
首先重载WndProc方法:
protected override void WndProc(ref Message m)
{
if (m.Msg == WM_NOTIFY && WmNotify(ref m)) {
// it's handled in WmNotify, WndProc does not handle it again.
return;
}
base.WndProc (ref m);
}
{
if (m.Msg == WM_NOTIFY && WmNotify(ref m)) {
// it's handled in WmNotify, WndProc does not handle it again.
return;
}
base.WndProc (ref m);
}
在WmNotify(ref m)中,比较Column的显示序号,如果不等,就表示Column的顺序被改变了,抛出ColumnReordered事件。ColumnReorderedEventArgs从CancalEventArgs派生,用户可以在事件接受里面拒绝更改Column的顺序。
private bool WmNotify(ref Message m) {
NMHDR nmhr = (NMHDR)Marshal.PtrToStructure(m.LParam, typeof(NMHDR));
if (nmhr.code != HDN_ENDDRAG) {
return false;
}
// it's end drag.
NMHEADER nmheader = (NMHEADER) m.GetLParam(typeof(NMHEADER));
if (nmheader.pItem == IntPtr.Zero) {
return false;
}
HDITEM hditem = (HDITEM) Marshal.PtrToStructure(nmheader.pItem, typeof(HDITEM));
if ((hditem.mask & HDI_ORDER) == HDI_ORDER) {
// it's changing column order..
int oldIndex = GetColumnDisplayIndex(nmheader.iItem);
int newIndex = hditem.iOrder;
if (oldIndex != newIndex) {
// raise ColumnReordered event.
ColumnHeader header = Columns[nmheader.iItem];
ColumnReorderedEventArgs e = new ColumnReorderedEventArgs(newIndex, oldIndex, header);
OnColumnReordered(e);
if (e.Cancel) {
// column reorder is canceled.
m.Result = new IntPtr(Convert.ToInt32(true));
return true;
}
return false;
}
}
return false;
}由于,Column的顺序改变以后,ListView的Columns里面ColumnHeader的顺序并没有被改变,改变的只是ColumnHeader的显示顺序,所以有必要提供方法,让用户获取某列的显示顺序。
public int GetColumnDisplayIndex(int index) {
LVCOLUMN column = new LVCOLUMN();
column.mask = LVCF_ORDER;
SendMessage(Handle, LVM_GETCOLUMN, index, ref column);
return column.iOrder;
}
程序用到了很多Win32的常量和数据结构,可以查看MSDN获取详细信息。点击这里下载完整源代码>>



浙公网安备 33010602011771号