I want to show a tooltip when hovering over a button and as long as the mouse is over the button the tooltip should follow the mouse. What is the correct way to achieve that?

When I add a MouseMove event that calls tooltip.Show(...) with the updated mouse position it flickers extremely, and also redraws the tooltip when the mouse rests. And if it is an OwnerDraw tooltip I can see the default system tooltip style "fighting" with the self-drawn tooltip.


I've noticed that when manually showing a tooltip with OnMouseHover, OnMouseMove gets called one more time after the tooltip is shown. As a hack, I've ignored the next OnMouseMove call immediately following the tooltip being shown (using a flag). Perhaps a similar phenomenon is occurring?

+1  A: 

OK, this may be complete overkill, and probably not the best solution, but I think a fun little hack nonthless.

Basically, I'm drawing a ListView at the location of the mouse. Some code:

ListView v = new ListView();
        public Form1()
            v.Height = 30;
            v.Width = 50;
            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;
+1 for the overkill-yet-rather-effective factor
+2  A: 

Indeed, with .Net 2.0 the ToolTip object has been altered. Before 2.0, there were some inconsistency problems when the ToolTip text was changed while the ToolTip was active, or with some other situations. Since 2.0, the Tooltip is hidden each time something happens what could affect the currently active Tooltip.

While this solved some problems, it now causes some events being fired right after e.g. a SetToolTip(), even if this function has been called from within this very event, resulting in an endless loop of ToolTip draw/hide until the mouse moves away from the ToolTip area.

My own workaround is to check whether the ToolTip is already the same and omitting the Set ToolTip() if so. (simply omitting the next event by a static flag as suggested above can cause problems as there is no guarantee that there will be a new event right after, e.g. if the mouse has just touched the ToolTip area and moved away already).

Also, using OnMouseHover just to display a Tooltip disables the internal timer fucntionality of the ToolTip component as well as causing many many unnecessary events and therefore wastes processor time. The Popup Event of the ToolTip component serves well as point of action.

In this special case, however, OnMouse Hover is necessary to track the mouse movement. Anyways, altering the ToolTip position causes a complete redraw of the Tooltip and therefore flicker. This can be reduced for a motionless mouse by checking whether the mouse position has changed between two events. Unfortunately, the ToolTip component has no way to change the position of the ToolTip adn is shown always relative to the current mouse position. So the only way to have it follow the mouse is to close and redraw it.

it MAY help to set the UseFading and/or UseAnimation properties to false so the flicker can be further reduced.

I found that testing for the same location eliminated my flickering and other problems