【问题标题】:custom button MouseLeave event自定义按钮 MouseLeave 事件
【发布时间】:2010-12-23 22:32:48
【问题描述】:

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

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

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

右侧按钮锁定在“悬停”状态。

我该如何解决这个问题?

谢谢。

【问题讨论】:

  • 你能分享你的代码吗?
  • 我一直在尝试这个故障一段时间,但我无法让它在悬停状态下卡住。也许你应该发布一些代码?
  • 当然,这里是:pastebin.com/Hh1d2pnc 我必须为每个面板和图片框提供 click 事件和 mouseleave,因为如果我将事件添加到它下方的用户控件,它不会触发事件一点也不。在第 69 行,我检查鼠标是否真的离开了控件。

标签: c# .net custom-controls mouseevent


【解决方案1】:

天啊……真是一团糟!
首先,UserControls 非常有问题。我建议你让你的控件继承自 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 张图片作为按钮,我无法在不拉伸图片的情况下调整它的大小。
  • 您不必这样做。把图片和你当前的代码文件(包括设计师)发给我,我会给你一个完整的工作控件!
  • jesconsultancy.nl/JeS/cutom_btn.zip 我找不到电子邮件或 PM 系统,所以就在这里。感谢您的帮助:)
  • 好的。我已经保存了,明天早上我会成功的。如果我不睡觉,我妈妈威胁我要割断我的喉咙。 (凌晨 1 点 57 分)
  • @Jelle 我完成了!它不需要图像,更新快如闪电,看起来非常流畅!我指望您了解我所做的并根据您自己的需要修改所有内容! pastebin.com/raw.php?i=Eszg4Quh 编辑:糟糕的错误事件!但我相信你会举办正确的活动,对吧?
【解决方案2】:

当鼠标离开客户区时,您应该会自动收到 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;
    }

希望对您有所帮助。

【讨论】:

  • 问题不在于事件本身。问题是发生时需要更新的 7 个图片框。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-12
  • 2022-12-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多