当鼠标仍然按下时,如何防止在 Winforms Listview 中立即触发 MouseUp 事件?

Posted

技术标签:

【中文标题】当鼠标仍然按下时,如何防止在 Winforms Listview 中立即触发 MouseUp 事件?【英文标题】:How to prevent immediate firing of MouseUp event in Winforms Listview when the mouse is still down? 【发布时间】:2021-04-28 07:44:29 【问题描述】:

基本上,如果您有一个打开了多选的标准 Listview,则鼠标向上和向下事件可以正常工作。

但是,如果您关闭多选并在 Listview 上单击并按住鼠标按钮,它会在鼠标按钮仍然按下时立即触发 down 和 up 事件。

有没有办法防止这种情况发生?我只希望释放鼠标按钮时触发鼠标向上事件。

【问题讨论】:

【参考方案1】:

WndProc中的ListView鼠标事件处理有点复杂。这就是我可以通过覆盖 OnMouseUpWndProc 来停止引发不必要的 MouseUp 的方法:

using System.Collections.Specialized;
using System.Reflection;
using System.Windows.Forms;
public class MyListView : ListView

    const int WM_LBUTTONUP = 0x0202, WM_RBUTTONUP = 0x0205, WM_MBUTTONUP = 0x0208;
    const int LISTVIEWSTATE_mouseUpFired = 0x00080000;
    FieldInfo listViewStateField;
    public MyListView()
    
        listViewStateField = (typeof(ListView)).GetField("listViewState",
               BindingFlags.NonPublic | BindingFlags.Instance);
    
    protected override void WndProc(ref Message m)
    
        if (m.Msg == WM_LBUTTONUP || m.Msg == WM_MBUTTONUP || m.Msg == WM_RBUTTONUP) 
            var value = (BitVector32)listViewStateField.GetValue(this);
            value[LISTVIEWSTATE_mouseUpFired] = true;
            listViewStateField.SetValue(this, value);
            var x = (m.LParam.ToInt32() & 0xffff);
            var y = (m.LParam.ToInt32() >> 16) & 0xffff;
            var e = new MouseEventArgs(
                m.Msg == WM_LBUTTONUP ? MouseButtons.Left :
                m.Msg == WM_MBUTTONUP ? MouseButtons.Middle :
                MouseButtons.Right, 1, x, y, 0);
            OnMouseUp(e);
        
        base.WndProc(ref m);
    
    protected override void OnMouseUp(MouseEventArgs e)
    
        if (Control.MouseButtons == MouseButtons.None)
            base.OnMouseUp(e);
    

【讨论】:

谢谢,它似乎工作得更好,但是当我使用鼠标向下/移动来移动表单时,会出现一些奇怪的行为,它会跳跃/滑动。不知道发生了什么。 我怀疑它可能与自定义实现有关。它与表单移动(非客户区鼠标消息)没有任何关系。在我身边的示例中没有看到这种行为。 @JoanVenge 使用默认表单和拦截相关WM-s 以移动和调整大小的自定义表单进行测试。两者都适用,没有任何问题。 谢谢很多人,我会再试一次。 @JoanVenge 你对此有结论吗?

以上是关于当鼠标仍然按下时,如何防止在 Winforms Listview 中立即触发 MouseUp 事件?的主要内容,如果未能解决你的问题,请参考以下文章

鼠标按下时CSS光标更改不起作用

当按下鼠标并释放鼠标时,如何保存鼠标位置?

鼠标左键按下时如何更改鼠标光标?

如何在鼠标左键按下时触发循环 autoclicker c++

Twitter Bootstrap 工具提示:鼠标按下时闪烁

如何在鼠标按下时重复调用一个函数?