C#列表视图控制ColumnHeader的MouseDown和MouseUp事件
我试图在listview的列标题中捕获MouseDown和MouseUp事件,以便通过insider listview的标题移动父窗体 实际上,我可以通过覆盖WndPrc来实现这一点,但它只在listview区域内工作,而不在columnheader中工作。虽然通过表单的insider listview标题移动表单的想法是好的(因为我的listview不能通过列单击进行排序),但从listview中的任何位置移动表单肯定是不好的。这将导致移动的每一项点击,这可能是非常令人不安的 说我们可以为list/listview控件创建自定义标题控件,但尽管我进行了所有搜索,我还是找不到C#/VB.Net的示例 有人知道如何实现这一点,或者有人举过一个例子吗C#列表视图控制ColumnHeader的MouseDown和MouseUp事件,c#,.net,vb.net,C#,.net,Vb.net,我试图在listview的列标题中捕获MouseDown和MouseUp事件,以便通过insider listview的标题移动父窗体 实际上,我可以通过覆盖WndPrc来实现这一点,但它只在listview区域内工作,而不在columnheader中工作。虽然通过表单的insider listview标题移动表单的想法是好的(因为我的listview不能通过列单击进行排序),但从listview中的任何位置移动表单肯定是不好的。这将导致移动的每一项点击,这可能是非常令人不安的 说我们可以为li
现在非常感谢。事实上,这很简单。 我分享我开发的代码,以防任何人需要
public class lw : ListView
{
const int LVM_FIRST = 0x1000;
const int LVM_GETHEADER = (LVM_FIRST + 31);
ListViewColumnHeaderWindow Header;
public lw()
{
//add 3 items for experiment
ListViewItem lwItem = new ListViewItem("a");
lwItem.SubItems.Add("b");
lwItem.SubItems.Add("c");
Items.Add(lwItem);
lwItem = new ListViewItem("d");
lwItem.SubItems.Add("e");
lwItem.SubItems.Add("f");
Items.Add(lwItem);
lwItem = new ListViewItem("g");
lwItem.SubItems.Add("h");
lwItem.SubItems.Add("i");
Items.Add(lwItem);
}
protected override void OnHandleCreated(EventArgs e)
{
base.OnHandleCreated(e);
//here we need to wrap the header window to listen it's WndProc messages
IntPtr hHeader = (IntPtr)SendMessage(Handle, LVM_GETHEADER, IntPtr.Zero, IntPtr.Zero);
Console.WriteLine("Creating ListViewColumnHeaderWindow for LVM_GETHEADER IntPtr {0}", hHeader);
Header = new ListViewColumnHeaderWindow(hHeader, this);
}
public void OnColumnMouseDown(object state)
{
Console.WriteLine("Header.MouseDown @{0}", (Point)state);
//now I can start to move the form from this point...
}
public void OnColumnMouseUp()
{
Console.WriteLine("Header.MouseUp");
}
public void MoveFromHeader(Point p) {
Console.WriteLine("Mouse moved to @{0}", p);
}
}
class ListViewColumnHeaderWindow : NativeWindow
{
lw Parent;
bool MouseIsDown;
System.Threading.Timer MTIMER;
public ListViewColumnHeaderWindow(IntPtr hHeader, lw parent)
{
Parent = parent;
MouseIsDown = false;
AssignHandle(hHeader);
}
protected override void WndProc(ref Message m)
{
if (MouseIsDown && m.Msg == 4608)
{
//this message is being sent when user starts to RESIZE
//the column header by clicking the column resizer.
//We should immediately cancel the mousedown event
//to allow user to resize the column (instead of moving the form)
MouseIsDown = false;
MTIMER?.Dispose();
}
switch (msg)
{
case 513: // WM_LBUTTONDOWN
MouseIsDown = true;
//due to possible column header resizing,
//I don't call OnColumnMouseDown event immediately here,
//but set a delay to detect the message '4608'
//which is being sent right after WM_LBUTTONDOWN
//that indicates the mouse is down to column resizing.
MTIMER?.Dispose();
MTIMER = new System.Threading.Timer(Parent.OnColumnMouseDown, new Point(m.LParam.ToInt32()), 200, System.Threading.Timeout.Infinite);
break;
case 512: // WM_MOUSEMOVE
if (MouseIsDown)
Parent.MoveFromHeader(new Point(m.LParam.ToInt32()));
break;
case 514: // WM_LBUTTONUP
if (MouseIsDown)
{
MouseIsDown = false;
Parent.OnColumnMouseUp();
}
break;
}
base.WndProc(ref m);
}
}
每小时有数百万人使用的移动表单的默认方式有什么问题,其中一个人拖动表单的标题栏?我从来没有看过listview列标题,并认为“这看起来不可点击,我打赌我可以使用它拖动整个表单”-您正在创建一个非常奇怪的UI体验?!这很难做到,因为列标题本身就是一个窗口。获取该窗口的句柄并为其注册鼠标事件完全不在Winforms中涵盖。您需要发送LVM_GETHEADER消息来获取句柄,用NativeWindow派生类包装它,并重写其WndProc()方法来获取鼠标通知。@CaiusJard父窗体边框为none。这是一个无边界的窗口(它必须是为了节省空间,以防你也质疑)