Claus Jensen
Claus Jensen

Reputation: 21

Getting a tooltip in a user control to show databound text and stay open

I have a user control that shows a TextBox along with a small help icon.

My goal is to have a ToolTip pop-up, show some databound text and stay open when the mouse hovers over the help icon.

So, to that end I have created a HelpText dependency property in the user control allowing me to bind a help text string to the user control.

So, my user control looks something like this

<UserControl Name="textField" ...>
    <StackPanel Orientation="Horizontal">
        <TextBox Text="{Binding ElementName=textField,Path=Text}"/>
        <Image Source="{StaticResource Help.Icon}">
            <Image.ToolTip>
                <ToolTip Content="{Binding ElementName=textField,Path=HelpText}"/>
            </Image.ToolTip>
        </Image>
    </StackPanel>
</UserControl>

This code does show the tooltip, except that it is empty! Also, the StaysOpen property does not make any difference as the tooltip shuts down after a few seconds.

Funny thing is that when I set the same binding directly on the Image control's ToolTip property the bound text is shown allright in the tooltip pop-up, however it still does not stay open:

<Image Source="{StaticResource Help.Icon}" ToolTip="{Binding ElementName=textField,Path=HelpText}">

So my to questions are:

  1. How come the binding against the user control's HelpText dependency property does not work in the first code sample but does work in the second?
  2. How do I make the ToolTip stay open or rather how do I make the ToolTip both stay open and show the databound text?

Thanks!

Upvotes: 2

Views: 5070

Answers (1)

Rachel
Rachel

Reputation: 132548

ToolTips are not part of the same VisualTree as the rest of your XAML, so the DataContext is not inherited the way you would expect it to be.

Writing ToolTip="{Binding SomeProperty}" will automatically set the ToolTip's DataContext to SomeProperty, however if you build a custom ToolTip you must do this yourself.

<ToolTip DataContext="{Binding PlacementTarget.DataContext, 
        RelativeSource={RelativeSource Self}}" ... />

This will bind the ToolTip's DataContext to the DataContext of whatever object the ToolTip is on.

To accomplish what you're trying to do, your <ToolTip> would probably look like this, since PlacementTarget would be your Image:

<!-- Could also use something like Tag if DataContext is actually used -->
<Image DataContext="{Binding ElementName=textField, Path=HelpText}" 
       Source="{StaticResource Help.Icon}">
    <Image.ToolTip>
        <ToolTip Content="{Binding PlacementTarget.DataContext, 
            RelativeSource={RelativeSource Self}}"/>
    </Image.ToolTip>
</Image>

As for why it won't stay open, I'm not positive but it might be because the ToolTipService.ShowDuration property defaults to 5 seconds, and that probably overwrites the StaysOpen property.

You can try setting it to something higher, such as

<Image ToolTipService.ShowDuration="60000" ... />

Or you can try this workaround of using a Popup styled to look like a ToolTip instead. The code would probably look something like this:

<Popup PlacementTarget="{Binding ElementName=MyImage}" 
       IsOpen="{Binding IsMouseOver, ElementName=MyImage, Mode=OneWay}">
    <TextBlock Text="{Binding ElementName=textField, Path=HelpText}" />
</Popup>

Upvotes: 14

Related Questions