Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/285.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#列表视图控制ColumnHeader的MouseDown和MouseUp事件_C#_.net_Vb.net - Fatal编程技术网

C#列表视图控制ColumnHeader的MouseDown和MouseUp事件

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

我试图在listview的列标题中捕获MouseDown和MouseUp事件,以便通过insider listview的标题移动父窗体

实际上,我可以通过覆盖WndPrc来实现这一点,但它只在listview区域内工作,而不在columnheader中工作。虽然通过表单的insider listview标题移动表单的想法是好的(因为我的listview不能通过列单击进行排序),但从listview中的任何位置移动表单肯定是不好的。这将导致移动的每一项点击,这可能是非常令人不安的

说我们可以为list/listview控件创建自定义标题控件,但尽管我进行了所有搜索,我还是找不到C#/VB.Net的示例

有人知道如何实现这一点,或者有人举过一个例子吗


现在非常感谢。

事实上,这很简单。 我分享我开发的代码,以防任何人需要

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。这是一个无边界的窗口(它必须是为了节省空间,以防你也质疑)