views:

666

answers:

3

I'm writing a calendar control in .Net WinForms that will show a tooltip for each date.

What's the best way to determine when to show the tooltip?

Showing it immediately in MouseMove would make it get in the way, so I'd like it to show when the mouse hovers over each date cell.

The MouseHover event only fires on the first hover after MouseEnter, so I can't use it.

What's the best way to do this?

EDIT:I'm using WinForms

A: 

Have a look at the AutoPopDelay, InitialDelay and ReshowDelay properties of the ToolTip class, as they control the behaviour of the tooltip.

I generally play around with the values until I get something that 'feels' right. It's annoying when a tooltip shows immediately, and for short tooltips, it's also annoying when they disappear too soon. For really long tooltips, say, several paragraphs (yes, poor design decision, but if there's a lot of info to read, at least let me read it!) then it should stay open as long as my mouse is stationary.

A tooltip example from MSDN gives the following values:

 AutoPopDelay = 5000;
 InitialDelay = 1000;
 ReshowDelay = 500;
 // Force the ToolTip text to be displayed whether or not the form is active.
 ShowAlways = true;

As mentioned in a comment, the poster wants to trigger the tooltip programatically. For that, ToolTip.Show( ) needs to be called. To get a delay effect, you'll likely want to have a timer running which counts the time that the mouse is stationary. Whenever the mouse enters, leaves or moves within the control, this time should be reset.

Charlie Salts
The problem is that I want to show the tooltip when each cell is hovered on, not just when the entire control is hovered on. The ToolTip class (AFAIK) doesn't support this natively, so I have to show it myself. The question is, when should I show it?
SLaks
A: 

It would be helpful to know which technology you are using (ASP.NET? Forms? WPF?) because they all have different ways of implementing tooltips:

  • With ASP.NET, you can simply set the ToolTip property of a control (such as a Label control that shows a number in your calendar), and it will automatically show a tooltip after a slight delay when hovering over the control.
  • In Forms, I think you have to actually create a ToolTip object then attach a control to it.
  • In WPF, you can add a Label.ToolTip element to your XAML code.

In all cases, though, there's a built-in way to do it, so it might not be necessary for you to write your own code at all.

If your situation is so custom that you do need to write your own code, I'd really need to know more about how you are representing the numbers in your calendar to help you out.

Last thing: you didn't really ask this--and it may not be under your control--but you might want to ask yourself whether a tooltip is the best way to show calendar information in the first place. If space is really tight, then the answer might be "yes", but if you have enough space to show the calendar events (or even the first few words of each event), this would save the user from having to "scrub the whole calendar" (i.e., roll over each date individually).

-Dan

DanM
"In all cases, though, there's a built-in way to do it, so it might not be necessary for you to write your own code at all." - So not true. It is true for simple situations (i.e., hovering over a button), but in some controls you need to control the behavior yourself, and it is not made easy due to the behavior of MouseHover.
Ed Swangren
Hi Ed,So, I'm guessing even the built-in ToolTip control relies on MouseHover, and it's just not reliable enough to show the tooltip every time? I guess I have noticed that a few times.In that case, I wonder if it would work to do something like this:1. On Control_MouseEnter, create a Timer object with Interval = 500ms.2. On Timer_Elapsed, show the tooltip.3. On Control_MouseLeave, hide the tooltip.
DanM
The problem is that I want to show the tooltip when each cell is hovered on, not just when the entire control is hovered on. MouseHover will only fire once for the entire control, and I want to show it only if ther cell is being hovered on (if the mouse is staying still), not just as soon as the mouse moves in.
SLaks
Okay, I think I see what you're getting at. It looks like Kevin has the right answer.
DanM
@DanThMan: I have done something similar before. I guess I was really referring to custom controls that need custom behavior, like maybe a circular control, or a controls which should show different things based on the context. For simply stuff the built in way works well enough, and the behavior is similar across many apps.
Ed Swangren
+5  A: 

The time delay between Enter and Hover is specified in SystemInformation.MouseHoverTime.

If for some reason the built-in tooltip handling code for whichever UI framework you're using isn't sufficient, you could just spin up a Timer after each MouseMove and show a Tooltip when it fires. Obviously, you'd need to reset the Timer each time the mouse is moved to prevent a long series "rain of tooltips".

Kevin Montrose
I should also show the tooltip if the mouse does move, but stays within MouseHoverSize; this is harder then it seems. (Would I have to store each move so I can check after MouseHoverTime whether it stayed near it?)
SLaks
@SLaks - You'd restart the Timer whenever the mouse left the rectangle defined by MouseHoverSize as read when you first started the Timer. You'd only have to store one Point/Rect (depending on implementation).
Kevin Montrose
No, because what if it then stays within the rectangle it started in the middle? (What if it moved a half of MouseHoverSize, and then another three quarters of MouseHoverSize, so that it's within MouseHoverSize of the point it moved to previously?)
SLaks
You don't update the bounds on every mouse move, only on those that result in a reset Timer.
Kevin Montrose
Are you sure?
SLaks