пользовательская кнопка MouseLeave событие



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



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



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



Кнопка справа заблокирована в режиме " hover" государство.



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



Спасибо.

563   2  

2 ответов:

Свят... Вот это бардак!
Во-первых, UserControls очень глючны. Я предлагаю вам сделать свой контроль наследуемым от Control вместо этого и нарисовать изображение и текст самостоятельно.
Во-вторых, почему вы используете отражение?
В-третьих, почему существует так много элементов управления?

Это событие пропускается, потому что требуется слишком много для обновления!

Вот некоторый код для возможного управления simples, который никогда не пропустит событие:

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

Вы должны получать сообщение WM_MOUSELEAVE windows автоматически, когда мышь покидает клиентскую область, и базовый класс обработки этого сообщения вызовет метод 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;
    }

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

Comments

    Ничего не найдено.