自定义按钮MouseLeave事件

时间:2010-12-23 22:32:49

标签: c# .net custom-controls mouseevent

我制作了一个带有面板和图片框的自定义按钮。使用MouseEnter和MouseLeave,我设置适当的悬停图像,如普通按钮。

问题是如果我在控件上移动鼠标太快,它有时不会触发MouseLeave事件。这样,按钮在悬停状态下“锁定”。

截图问题: http://www.jesconsultancy.nl/images/screens/screen_prblm.png

右边的按钮被锁定在“悬停”状态。

我该如何解决这个问题?

感谢。

2 个答案:

答案 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;
    }

希望有所帮助。