我制作了一个带有面板和图片框的自定义按钮。使用MouseEnter和MouseLeave,我设置适当的悬停图像,如普通按钮。
问题是如果我在控件上移动鼠标太快,它有时不会触发MouseLeave事件。这样,按钮在悬停状态下“锁定”。
截图问题: http://www.jesconsultancy.nl/images/screens/screen_prblm.png
右边的按钮被锁定在“悬停”状态。
我该如何解决这个问题?
感谢。
答案 0 :(得分:1)
圣......这太乱了!
首先,UserControl
是非常错误的。我建议你让你的控件继承自Control
,然后自己绘制图像和文字
其次,为什么要使用反射?
第三,为什么有那么多控件?
这会错过这个事件,因为更新需要太多!
这里有一些简单控制的代码,永远不会错过任何一个事件:
using System;
using System.Drawing;
using System.Windows.Forms;
namespace lol
{
public class BlackWhiteControl : Control
{
protected override void OnMouseEnter(EventArgs e)
{
base.OnMouseEnter(e);
this.BackColor = Color.Black;
}
protected override void OnMouseLeave(EventArgs e)
{
base.OnMouseLeave(e);
this.BackColor = Color.White;
}
}
}
答案 1 :(得分:0)
当鼠标离开客户区时,您应该自动收到WM_MOUSELEAVE窗口消息,然后该消息的基类处理将调用OnMouseLeave方法。如果这真的没有发生,你当然可以解决它。只需直接拦截WM_MOUSEMOVE,然后进行Win32 API调用,请求在鼠标离开控件时通知您。
使用以下简单的WndProc覆盖...
private bool _mouseOver = false;
protected override void WndProc(ref Message m)
{
switch (m.Msg)
{
case PI.WM_MOUSEMOVE:
if (!_mouseOver)
{
PI.TRACKMOUSEEVENTS tme = new PI.TRACKMOUSEEVENTS();
tme.cbSize = (uint)Marshal.SizeOf(typeof(PI.TRACKMOUSEEVENTS));
tme.dwHoverTime = 100;
tme.dwFlags = (int)(PI.TME_LEAVE);
tme.hWnd = Handle;
PI.TrackMouseEvent(ref tme);
_mouseOver = true;
}
base.WndProc(ref m);
break;
case PI.WM_MOUSELEAVE:
_mouseOver = false;
base.WndProc(ref m);
break;
}
}
平台调用您需要的信息是......
internal const int WM_MOUSEMOVE = 0x0200;
internal const int WM_MOUSELEAVE = 0x02A3;
internal const int TME_LEAVE = 0x0002;
[StructLayout(LayoutKind.Sequential)]
internal struct TRACKMOUSEEVENTS
{
public uint cbSize;
public uint dwFlags;
public IntPtr hWnd;
public uint dwHoverTime;
}
希望有所帮助。