Reputation: 24789
I have made a custom control and when a condition is met, I want to show a tooltip:
protected override void OnMouseMove(MouseEventArgs e)
{
base.OnMouseMove(e);
var plannedItem = GetPlannedItemByPosition(e.Location);
if (plannedItem != null)
_tooltip.SetToolTip(this, plannedItem.Description);
else
_tooltip.RemoveAll();
}
This code works fine, excepts for the face that the tooltip flickers.
This custom control, paints all the information in the OnPaint
event, maybe this has something to do with it? And if it does, how can I prevent the tooltip from flickering?
Upvotes: 7
Views: 11101
Reputation: 11
c# (works on tooltip chart):
Point mem = new Point();
private void xxx_MouseMove(MouseEventArgs e){
// start
Point pos = e.Location;
if (pos == mem) { return; }
// your code here
// end
mem = pos
}
Upvotes: 1
Reputation: 2000
For the visitors of this thread, here is what I did, following suggestions above (VB.NET):
Dim LastToolTip As String
Private Sub PictureBox1_MouseMove(sender As Object, e As MouseEventArgs) Handles PictureBox1.MouseMove
Dim NewToolTip = CalculateTooltipText(e.X, e.Y)
If LastToolTip <> NewToolTip Then
ToolTip1.SetToolTip(PictureBox1, NewToolTip)
LastToolTip = NewToolTip
End If
End Sub
It stopped the flickering.
Upvotes: 0
Reputation: 2131
Remember last mouse position and set the tooltip only when the mouse position changes.
public partial class Form1 : Form
{
private int lastX;
private int lastY;
private void button1_MouseMove(object sender, MouseEventArgs e)
{
if (e.X != this.lastX || e.Y != this.lastY)
{
toolTip1.SetToolTip(button1, "test");
this.lastX = e.X;
this.lastY = e.Y;
}
}
Upvotes: 12
Reputation: 81610
Since this is a painted custom control, I think it might be easier to just have a variable hold the last shown tip, and instead of always "setting" the tooltip, just show it.
Simple example (using just a form):
public partial class Form1 : Form {
private List<TipRect> _Tips = new List<TipRect>();
private TipRect _LastTip;
private ToolTip _tooltip = new ToolTip();
public Form1() {
InitializeComponent();
_Tips.Add(new TipRect(new Rectangle(32, 32, 32, 32), "Tip #1"));
_Tips.Add(new TipRect(new Rectangle(100, 100, 32, 32), "Tip #2"));
}
private void Form1_Paint(object sender, PaintEventArgs e) {
foreach (TipRect tr in _Tips)
e.Graphics.FillRectangle(Brushes.Red, tr.Rect);
}
private void Form1_MouseMove(object sender, MouseEventArgs e) {
TipRect checkTip = GetTip(e.Location);
if (checkTip == null) {
_LastTip = null;
_tooltip.Hide(this);
} else {
if (checkTip != _LastTip) {
_LastTip = checkTip;
_tooltip.Show(checkTip.Text, this, e.Location.X + 10, e.Location.Y + 10, 1000);
}
}
}
private TipRect GetTip(Point p) {
TipRect value = null;
foreach (TipRect tr in _Tips) {
if (tr.Rect.Contains(p))
value = tr;
}
return value;
}
}
Here is the TipRect class I created to simulate whatever your PlannedItem class is:
public class TipRect {
public Rectangle Rect;
public string Text;
public TipRect(Rectangle r, string text) {
Rect = r;
Text = text;
}
}
Upvotes: 1
Reputation: 941327
This will happen when you display the tooltip at the mouse cursor position. As soon as the tip window shows up, Windows notices that the mouse is located in that window and posts a MouseMove message. Which makes the tooltip disappear. Which makes Windows send a MouseMove message to your control, running your OnMouseMove() method. Which makes the tooltip appear again. Etcetera, you'll see the tooltip rapidly flickering.
Solve this by any of the following methods:
Upvotes: 6
Reputation: 4407
I imagine your mouse does move a little when you think it is still. I suggest you do some kind of caching here - only call _tooltip.SetToolTip if the plannedItem has changed.
Upvotes: 0