Binding a ToolTip in XAML
So, I'm ramping up on XAML. In the smart client version of CMS, we'll allow the users to modify the content metadata on a two-column display (description on the left, text/check/combo box on the right). If the value is changed, a tooltip will show the previous value.
But there's a problem. According to the docs, ToolTips can't have a Parent; they're a brand new window without the hierarchy. So how do you bind it?
I posed the question to our internal Avalon Discussion alias, and recieved several replys. Figuring I'm not the only person to have experienced this problem (and having a known propensity towards tooltips), I thought I'd share them. But first, the setup:
I have a UserControl that wraps the behavior of description/___Box/Tooltip, so that the main page just drops one of these controls whenever it has a new textbox. This control is named "SGT", which has a dependency property OriginalValue. Here's what it looks like when I started out (note that it doesn't work-- ToolTip will not have access to SGT):
<UserControl x:Class="CMS_Client.Controls.SubmissionGridText"
xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
x:Name="SGT">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition SharedSizeGroup="Col0SizeGroup"></ColumnDefinition>
<ColumnDefinition SharedSizeGroup="Col1SizeGroup"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<TextBlock Name="Descriptn" Grid.Column="0" Grid.Row="0" Text="{Binding Description,ElementName=SGT}"></TextBlock>
<TextBox Name="ValueTextBox" Grid.Column="1" Grid.Row="0" Text="{Binding Value,ElementName=SGT}" ToolTipService.InitialShowDelay="500" ToolTipService.ShowDuration="60000">
<TextBox.ToolTip>
<ToolTip Name="PreviousValue" Placement="Right">
<TextBlock Text="{Binding OriginalValue,ElementName=SGT}"/>
</ToolTip>
</TextBox.ToolTip>
</TextBox>
</Grid>
</UserControl>
The first suggestion (Neil Kronlage) was to set the DataContext on the UserControl to be itself, and then the ToolTip would inherit that context:
<UserControl x:Class="CMS_Client.Controls.SubmissionGridText" xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
x:Name="SGT"
DataContext=”{Binding ElementName=SGT}”>
…
<TextBox.ToolTip>
<ToolTip Name="PreviousValue" Placement="Right">
<TextBlock Text="{Binding OriginalValue}"/> <!--this uses the datacontext -->
A second suggestion (Neil and Adam Smith) was that we could use PlacementTarget in the binding. This is nice, as I am actually inheriting the DataContext already from the page that hosts the DataControl, and this would allow the ToolTip to gain access back to the origial control. As Adam noted, though, you have to be aware of the parent/child structure off your markup:
<ToolTip Name="PreviousValue" Placement="Right"
DataContext=”{Binding RelativeSource={RelativeSource Self},Path=PlacementTarget.Parent.Parent}”>
<TextBlock Text="{Binding OriginalValue,ElementName=SGT}"/>
Hope that helps someone out there. Appologies if the formatting comes out odd; I pasted snippets right out of the emails.
Comments
Anonymous
November 06, 2006
Thanks for that tip: I've been thinking about this problem for a while, and the best I could come up with was setting the DataContext through code. The same trick should work for binding ContextMenus as well.Anonymous
June 24, 2007
Tom, THANK YOU!!! I've been trying super hard to data bind to data from the control that opened the tool tip. Setting a data context and a PlacementTarget solved my issues. My app now has the coolest tool tip and get data from the control I needed. One style and all controls can use this. You can download the entire application and presentation after 1:00pm EST on Sunday June 24th to see your data binding teaching in action! The control that uses this is a WPF textbox that work's just like the textbox in Microsoft Blend. I needed this for the application in the above download. Thank you, you have made my day, maybe my week! KarlAnonymous
June 10, 2008
You are the MAN ! Thank you so much !