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

3

如果您启用了多选功能的标准Listview,则鼠标上下事件将正常工作。

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

有没有办法防止这种情况发生?我只想在释放鼠标按钮时触发鼠标松开事件。

1个回答

2

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);
    }
}

谢谢,看起来它的表现更好了,但是当我使用鼠标按下/移动来移动窗体时,出现了一些奇怪的行为,它会跳跃/滑动。不确定发生了什么。 - Joan Venge
1
我怀疑这可能与自定义实现有关。它与表单移动(非客户区鼠标消息)无关。我在我的示例中没有看到这样的行为。 - Reza Aghaei
1
@JoanVenge 测试了默认表单和自定义表单,拦截相关的WM消息以移动和调整大小。两种表单都能完美运行,没有任何问题。 - dr.null
1
非常感谢大家,我会再试一次的。 - Joan Venge
@JoanVenge 你最终的结论是什么? - Reza Aghaei

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接