Привязка всплывающей подсказки Windows Forms к мыши

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

Когда я добавляю событие MouseMove, которое вызывает tooltip.Show(...) с обновленным положением мыши, оно сильно мерцает, а также перерисовывает всплывающую подсказку, когда мышь отдыхает. И если это всплывающая подсказка OwnerDraw, я вижу, что стиль системной всплывающей подсказки по умолчанию «борется» с саморисованной всплывающей подсказкой.


person Community    schedule 06.01.2009    source источник
comment
Ответ JMGross правильный, вы должны отметить его правильно!!   -  person Sherif    schedule 11.04.2011
comment
-1 за то, что не отметил правильный ответ :(   -  person Hybrid    schedule 18.02.2012


Ответы (3)


Действительно, в .Net 2.0 объект ToolTip был изменен. До версии 2.0 возникали некоторые проблемы с несогласованностью при изменении текста всплывающей подсказки, когда всплывающая подсказка была активной, или в некоторых других ситуациях. Начиная с версии 2.0, всплывающая подсказка скрывается каждый раз, когда происходит что-то, что может повлиять на текущую активную всплывающую подсказку.

Хотя это решило некоторые проблемы, теперь некоторые события запускаются сразу после, например. SetToolTip(), даже если эта функция была вызвана из этого самого события, что приводит к бесконечному циклу рисования/скрытия всплывающей подсказки до тех пор, пока мышь не переместится из области всплывающей подсказки.

Мой собственный обходной путь - проверить, является ли всплывающая подсказка уже такой же, и опустить Set ToolTip(), если это так. (простой пропуск следующего события с помощью статического флага, как было предложено выше, может вызвать проблемы, поскольку нет гарантии, что сразу после этого будет новое событие, например, если мышь только что коснулась области всплывающей подсказки и уже ушла).

Кроме того, использование OnMouseHover только для отображения всплывающей подсказки отключает функцию внутреннего таймера компонента всплывающей подсказки, а также вызывает множество ненужных событий и, следовательно, тратит процессорное время. Всплывающее событие компонента ToolTip также служит точкой действия.

Однако в этом особом случае OnMouse Hover необходим для отслеживания движения мыши. В любом случае изменение положения всплывающей подсказки вызывает полную перерисовку всплывающей подсказки и, следовательно, мерцание. Это можно уменьшить для неподвижной мыши, проверив, изменилось ли положение мыши между двумя событиями. К сожалению, компонент ToolTip не имеет возможности изменить положение всплывающей подсказки и всегда отображается относительно текущей позиции мыши. Таким образом, единственный способ заставить его следовать за мышью — это закрыть и перерисовать его.

МОЖЕТ помочь установить для свойств UseFading и/или UseAnimation значение false, чтобы можно было еще больше уменьшить мерцание.

person Community    schedule 14.05.2009
comment
Я обнаружил, что тестирование в одном и том же месте устранило мерцание и другие проблемы. - person arolson101; 24.08.2010

Хорошо, это может быть полным излишеством и, вероятно, не лучшим решением, но, тем не менее, я думаю, что это забавный маленький хак.

По сути, я рисую ListView в том месте, где находится мышь. Некоторый код:

ListView v = new ListView();
        public Form1()
        {
            InitializeComponent();
            v.Items.Add("Foo");
            v.Height = 30;
            v.Width = 50;
            this.button1.Controls.Add(v);
            v.MouseMove += new MouseEventHandler(v_MouseMove);
            v.BackColor = SystemColors.Info;

            this.button1.MouseMove += new MouseEventHandler(button1_MouseMove);
        }

        void v_MouseMove(object sender, MouseEventArgs e)
        {
            v.Location = new Point(v.Location.X + e.Location.X, v.Location.Y + e.Location.Y);
        }

        void button1_MouseMove(object sender, MouseEventArgs e)
        {
            v.Location = e.Location;
        }
person BFree    schedule 06.01.2009

Я заметил, что при ручном отображении всплывающей подсказки с помощью OnMouseHover OnMouseMove вызывается еще раз после отображения всплывающей подсказки. В качестве хака я проигнорировал следующий вызов OnMouseMove сразу после показа всплывающей подсказки (используя флаг). Возможно, имеет место подобное явление?

person lc.    schedule 06.01.2009