Getting a tooltip in a user control to show databo

2020-02-11 12:19发布

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!

1条回答
疯言疯语
2楼-- · 2020-02-11 13:06

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>
查看更多
登录 后发表回答