UserControl:如何添加 MouseWheel 监听器?

UserControl: How to add MouseWheel Listener?(UserControl:如何添加 MouseWheel 监听器?)
本文介绍了UserControl:如何添加 MouseWheel 监听器?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在创建一个 UserControl,如果鼠标悬停在控件上并且 MouseWheel 被旋转,它应该做出反应.

I'm creating an UserControl that should react if the mouse is over the control and MouseWheel gets rotated.

目前我正在这样做,如下所示:

Currently i'm doing this as shown here:

    public MyUserControl()
    {
        this.MouseWheel += new MouseEventHandler(MouseWheelHandler);
    }

    private void MouseWheelHandler(object sender, System.Windows.Forms.MouseEventArgs e)
    {
        if (e.Delta > 0)
            incIndex();

        if (e.Delta < 0)
            decIndex();
    }

    protected override void OnMouseEnter(EventArgs e)
    {
        this.Focus();

        base.OnMouseEnter(e);
    }

事实上这很好用,但问题在于this.Focus();"的部分因为它破坏了我的表单/应用程序行为.

In fact this works fine, but the problem is the part with the "this.Focus();" as it destroys my forms / applications behaviour.

有没有更好的方法来实现这一点?

Is there a better way to achive this?

推荐答案

遇到同样的问题,我终于实现了@Paul_Westcott 和@nr1 两种解决方案的混合.这是一个类似于@Paul_Westcott 的本地解决方案(仅适用于订阅的winforms 控件).它是多显示器安全和 MDI 安全的(与应用程序中的其他窗口重叠)

having the same problem, I finally implemented a mix of both solution by @Paul_Westcott and @nr1. This is a local solution like solution of @Paul_Westcott (only applies to the winforms control that subscribes to). It is multiple monitor safe and MDI safe (overlapping by other windows within the application)

public static class MouseWheelHandlerForWinformsControl
{
    private class MouseWheelMessageFilter : IMessageFilter
    {
        [DllImport("user32.dll")]
        private static extern IntPtr WindowFromPoint(Point pt);

        private readonly Control mCtrl;
        private readonly Action<MouseEventArgs> mOnMouseWheel;

        public MouseWheelMessageFilter(Control ctrl, Action<MouseEventArgs> onMouseWheel)
        {
            mCtrl = ctrl;
            mOnMouseWheel = onMouseWheel;
        }

        public bool PreFilterMessage(ref Message m)
        {
            // handle only mouse wheel messages
            if (m.Msg != 0x20a)
                return false;

            Point mouseAbsolutePosition = new Point(m.LParam.ToInt32());
            Point mouseRelativePosition = mCtrl.PointToClient(mouseAbsolutePosition);

            IntPtr hControlUnderMouse = WindowFromPoint(mouseAbsolutePosition);
            Control controlUnderMouse = Control.FromHandle(hControlUnderMouse);

            if (controlUnderMouse != mCtrl)
                return false;

            MouseButtons buttons = GetMouseButtons(m.WParam.ToInt32());
            int delta = m.WParam.ToInt32() >> 16;

            var e = new MouseEventArgs(buttons, 0, mouseRelativePosition.X, mouseRelativePosition.Y, delta);

            mOnMouseWheel(e);

            return true;
        }

        private static MouseButtons GetMouseButtons(int wParam)
        {
            MouseButtons buttons = MouseButtons.None;

            if(HasFlag(wParam, 0x0001)) buttons |= MouseButtons.Left;
            if(HasFlag(wParam, 0x0010)) buttons |= MouseButtons.Middle;
            if(HasFlag(wParam, 0x0002)) buttons |= MouseButtons.Right;
            if(HasFlag(wParam, 0x0020)) buttons |= MouseButtons.XButton1;
            if(HasFlag(wParam, 0x0040)) buttons |= MouseButtons.XButton2;

            return buttons;
        }

        private static bool HasFlag(int input, int flag)
        {
            return (input & flag) == flag;
        }
    }

    public static void MemorySafeAdd(Control ctrl, Action<MouseEventArgs> onMouseWheel)
    {
        if (ctrl == null || onMouseWheel == null)
            throw new ArgumentNullException();

        var filter = new MouseWheelMessageFilter(ctrl, onMouseWheel);
        Application.AddMessageFilter(filter);
        ctrl.Disposed += (s, e) => Application.RemoveMessageFilter(filter);
    }
}

一旦您将此帮助程序类添加到您的解决方案中,您就可以在一行中将控件 myControl 订阅到鼠标滚轮,如下所示:

Once you have added this helper class into your solution, you subscribe a control myControl to the mouse-wheel, in one line, as following:

public void Init() {
    MouseWheelHandlerForWinformsControl.MemorySafeAdd(myControl, OnMouseWheelEvent);
}

void OnMouseWheelEvent(MouseEventArgs args) {
    // do what you need here
}

这篇关于UserControl:如何添加 MouseWheel 监听器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本站部分内容来源互联网,如果有图片或者内容侵犯您的权益请联系我们删除!

相关文档推荐

DispatcherQueue null when trying to update Ui property in ViewModel(尝试更新ViewModel中的Ui属性时DispatcherQueue为空)
Drawing over all windows on multiple monitors(在多个监视器上绘制所有窗口)
Programmatically show the desktop(以编程方式显示桌面)
c# Generic Setlt;Tgt; implementation to access objects by type(按类型访问对象的C#泛型集实现)
InvalidOperationException When using Context Injection in ASP.Net Core(在ASP.NET核心中使用上下文注入时发生InvalidOperationException)
LINQ many-to-many relationship, how to write a correct WHERE clause?(LINQ多对多关系,如何写一个正确的WHERE子句?)