Прикрепление всплывающей подсказки Windows Forms к мыши
Я хочу показать всплывающую подсказку при наведении курсора на кнопку, и пока мышь находится над кнопкой, подсказка должна следовать за мышью. Как правильно достичь этого?
Когда я добавляю событие MouseMove, которое вызывает tooltip.Show (...) с обновленной позицией мыши, оно очень сильно мерцает, а также перерисовывает подсказку, когда мышь отдыхает. И если это всплывающая подсказка OwnerDraw, я могу видеть системный стиль всплывающей подсказки по умолчанию, который "сражается" с самозваной подсказкой.
3 ответа
Действительно, в.Net 2.0 объект ToolTip был изменен. До версии 2.0 возникали проблемы с несогласованностью, когда текст всплывающей подсказки изменялся во время активной подсказки или в некоторых других ситуациях. Начиная с версии 2.0, всплывающая подсказка скрывается каждый раз, когда происходит что-то, что может повлиять на текущую активную подсказку.
Хотя это решило некоторые проблемы, теперь оно вызывает некоторые события сразу после, например, SetToolTip(), даже если эта функция была вызвана из этого самого события, что приводит к бесконечному циклу рисования / скрытия ToolTip до тех пор, пока мышь не отойдет от область подсказок.
Мой собственный обходной путь - проверить, является ли ToolTip уже такой же, и опустить Set ToolTip (), если это так. (простое пропускание следующего события статическим флагом, как предложено выше, может вызвать проблемы, поскольку нет гарантии, что сразу после этого будет новое событие, например, если мышь только что коснулась области всплывающей подсказки и уже удалилась).
Кроме того, использование OnMouseHover только для отображения всплывающей подсказки отключает функцию внутреннего таймера компонента ToolTip, а также вызывает много ненужных событий и, следовательно, тратит процессорное время. Всплывающее событие компонента ToolTip также служит отправной точкой.
Однако в этом особом случае OnMouse Hover необходим для отслеживания движения мыши. В любом случае, изменение положения всплывающей подсказки вызывает полную перерисовку всплывающей подсказки и, следовательно, мерцание. Это может быть уменьшено для неподвижной мыши, проверяя, изменилось ли положение мыши между двумя событиями. К сожалению, компонент ToolTip не может изменить положение всплывающей подсказки, и она всегда отображается относительно текущей позиции мыши. Таким образом, единственный способ заставить его следовать за мышью - закрыть и перерисовать его.
это МОЖЕТ помочь установить для свойств UseFading и / или UseAnimation значение false, чтобы мерцание можно было еще больше уменьшить.
Ладно, это может быть излишним, и, возможно, не лучшим решением, но я думаю, что это забавный маленький хак.
По сути, я рисую 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;
}
Я заметил, что при ручном отображении всплывающей подсказки с помощью OnMouseHover OnMouseMove вызывается еще раз после показа всплывающей подсказки. Как хак, я проигнорировал следующий вызов OnMouseMove сразу после показанной всплывающей подсказки (с использованием флага). Возможно, подобное явление происходит?