问题描述
我创建一个用户控件应该作出反应,如果鼠标在控制和鼠标滚轮旋转得到
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);
}
在实际上这工作得很好,但问题是用这部分。焦点();因为它破坏我的表格/应用程序的行为。
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
}
这篇关于用户控件:如何添加鼠标滚轮侦听器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!