пользовательская кнопка MouseLeave событие - PullRequest
4 голосов
/ 24 декабря 2010

Я сделал пользовательскую кнопку с несколькими панелями и картинками. С помощью MouseEnter и MouseLeave я устанавливаю соответствующие изображения при наведении, как обычные кнопки.

Проблема в том, что если я слишком быстро перемещаю мышь по элементу управления, это иногда не вызывает событие MouseLeave. Таким образом, кнопка «заблокирована» в состоянии наведения.

проблема с скриншотом: http://www.jesconsultancy.nl/images/screens/screen_prblm.png

кнопка справа заблокирована в состоянии «зависания».

Как я могу решить это?

Спасибо.

Ответы [ 2 ]

1 голос
/ 24 декабря 2010

Святой ... Это беспорядок!
Во-первых, 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;
        }
    }
}
0 голосов
/ 24 декабря 2010

Вы должны получить сообщение окна 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;
    }

Надеюсь, что поможет.

...