7

I'm trying to implement a tool-tip system in a WPF MVVM application. The tool-tip is supposed to appear in a certain Label that is a part of the MainWindow (not hovering at the mouse pointer) and should happen on mouse-over (ideally with a configurable delay, but that is unimportant), calling a method in the appropriate ViewModel. The ViewModel will then deal with contacting the Model layer that will resolve which tool-tip to display etc.

My problem is how to get a mouse-over event from the view to the ViewModel, along with the identity of the object that fired the event (so I can resolve the right tool-tip for it). Let's say I have a <Label Name="MyLabel" Content="This is a label" /> in my SettingsView.xaml, how do I get it to call the GetTooltip(string id) method in SettingsViewModel with MyLabel as the argument (or otherwise accessible) on mouse-over? Can I use a regular <Trigger> to do it somehow?

Swooper
  • 359
  • 4
  • 13
  • 2
    Check out this link to see if building Commands and binding to them on normally "Uncommanded" controls might solve your problem. http://blogs.microsoft.co.il/blogs/tomershamam/archive/2009/04/14/wpf-commands-everywhere.aspx – Dave White May 03 '11 at 20:37
  • @Dave: This should be an answer.. I'd like to upvote it =) – Jens May 04 '11 at 06:52
  • @Jens - All done. I've added a bit as well. Thanks for the suggestion. – Dave White May 04 '11 at 15:52

3 Answers3

2

What you need to do is hook up some commands (the preferred approach for ViewModels to interact with events in the View) to the Mouse events and then "populate" your "tooltip" control with the appropriate information.

For example, your ViewModel has a ToolTip property (that represents a one-way, get only ToolTipViewModel) that can be bound to an area of your UI (with a DataTemplate). You bind up to the new "MouseOver" command and populate/nullify the object that is in your ToolTipViewModel property based on the commands. This allows for testability, zero-code behind, and using DataTemplates to build your tooltip presentation.

Check out this link to see if building Commands and binding to them on normally "Uncommanded" controls might solve your problem.

Dave White
  • 3,451
  • 1
  • 20
  • 25
1

First, have you tried the built-in ToolTip control? It might give you what you need for free, and it can be styled/templated to host complex content.

Second, you may be able to use the MouseEnter event available on every WPF control. You'd have to attach your handler to the controls you want to support, though.

In order to generically cover every control, consider attaching a handler to the parent Window's PreviewMouseMove event (or override OnPreviewMouseMove in the Window's code-behind), which will be called whenever any child element is about to receive one. You can then find out what control is under the mouse pointer by using HitTest. This isn't terribly efficient, though, which is why you may be better-off with the built-in ToolTip control.

Community
  • 1
  • 1
Chris Wenham
  • 23,679
  • 13
  • 59
  • 69
  • I could use `ToolTip`, yes, but as I said, I don't want the text to appear on the mousepointer, I want it to appear in an area at the bottom of the mainwindow. MouseEnter might work (I'd just have to have a seperate event to clear the tooltip on MouseLeave I guess). I'll examine the rest of your answer better tomorrow - the generic coverage idea sounds good, I assumed I'd need to put an event on every control I wanted a tooltip on but if this works I might not have to. Thanks for now! – Swooper May 03 '11 at 20:57
0

Create a Popup control with a nested TextBlock in your control template (make a style for the label), bind its visibility property to when IsMouseOver, and bind the PlacementTarget to the control at the bottom of the window where you want it to appear. Finetune with Horizontal/Vertical offset properties.

Dominic
  • 62,658
  • 20
  • 139
  • 163