This is the next sample in the WPF Sample Applications Series. The purpose of the Sample Series is to provide concise code solutions for specific programming tasks. This sample provides a brief description of the problem, the solution and full source code with a test bench program.
In a previous sample it was stated that, “One of the most powerful features in the WPF platform is its rich data binding.” In this sample we will see how data binding can be used to display data bound values in a ToolTip.
ToolTips are really just little read-only popup windows that display some context sensitive information related to the object that the ToolTip belongs to. With WPF’s very rich content rendering and control styling capabilities, ToolTips are not longer limited to a plain text. Developers can very easily add images, 3D objects, paths, visuals, text, grids or just about anything to a ToolTip. You can also make a ToolTip an irregular shaped window! OK, just because we can, does not mean we should. Oh well, I did this and have included a very cool Vista TaskBar application preview style ToolTip.
ToolTips are controlled by a ToolTipService. You can set ToolTipService attached properties on your ToolTips to control them. The ToolTipService Class article covers the properties exposed by the ToolTipService Class and examples on using it to control the position of the ToolTip. In fact, this sample uses the ToolTipService.SetHasDropShadow method to turn off the default drop shadow so that our cool Vista TaskBar ToolTip can use a different method for rendering its outer glow, just like Vista does.
There are four methods that I know of that developers can use to code their ToolTips. This sample demonstrates all four methods.
-
Entering a string in the ToolTip property of an object
-
Code the ToolTip in the controls XAML mark-up.
-
Code the ToolTip using XAML in a resource and apply that resource to one or more controls
-
Code the ToolTip in the code behind file, VB.NET or C#.
This sample will also cover using data binding in the 2nd and 3rd methods and how to use a VisualBrush in the 4th method.
Sample Application
When you first open the application, it looks like the above image. I have entered my name and secret password.
Name ToolTip
At last, a ToolTip in a ToolTip article! I have hovered my mouse over the Name TextBox and the cool data bound ToolTip pops up. This is a very vanilla ToolTip from a design perspective but is rich in data binding. Two properties Text and ActualWidth, from the TextBox control are data bound and rendered in the ToolTip. You can data bind whatever properties your application needs to display.
Let’s have a look at the XAML mark-up resource that was used to render this ToolTip. The blue lines of code will be commented on below.
<ToolTip x:Key=”toolTipTextBoxBinding”
DataContext=”{Binding Path=PlacementTarget,
RelativeSource={x:Static RelativeSource.Self}}”>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width=”Auto”/>
<ColumnDefinition Width=”*”/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height=”Auto”/>
<RowDefinition Height=”Auto”/>
<RowDefinition Height=”Auto”/>
</Grid.RowDefinitions>
<Border HorizontalAlignment=”Stretch”
BorderThickness=”0,0,0,1″ BorderBrush=”Black”
Margin=”5″ Grid.Column=”0″
Grid.Row=”0″ Grid.ColumnSpan=”2″>
<TextBlock FontSize=”14″>
Two TextBox Data Bound Properties</TextBlock>
</Border>
<TextBlock Grid.Column=”0″ Grid.Row=”1″
Margin=”10,0,5,0″>TextBox.Text is:</TextBlock>
<TextBlock Grid.Column=”1″ Grid.Row=”1″
FontWeight=”Bold” Text=”{Binding Path=Text}”/>
<TextBlock Grid.Column=”0″ Grid.Row=”2″
Margin=”10,0,5,0″>TextBox.ActualWidth is:</TextBlock>
<TextBlock Grid.Column=”1″ Grid.Row=”2″
FontWeight=”Bold” Text=”{Binding Path=ActualWidth}”/>
</Grid>
</ToolTip>
</Window.Resources>
The key piece of code is the DataContext property. It’s here that the ToolTip’s DataContext is established, allowing child controls of the ToolTip to data bind to properties in the DataContext. In the DataContext data binding code, PlacementTarget Property refers to the TextBox that opened the ToolTip. The RelativeSource is set to the ToolTip. So the ToolTip’s DataContext is itself, with the data binding Path being the TextBox that this ToolTip is associated with. If you don’t have to reread this several times, you’re way smarter than me.
The second piece of code that makes this work, is located in the two TextBlocks with their Text properties data bound to properties on the TextBox control. In this example we are data binding to the Text and ActualWidth properties.
So you can see how simple this really is. The remained of the XAML mark-up is straightforward. Check out how I used the border control to provide an underline that created a heading section for the ToolTip. I could have used underlined text in the heading area, but this looks better.
Password ToolTip
This simple ToolTip using data binding to bind two properties Password and ActualWidth, from the PasswordBox control are data bound and rendered in the ToolTip. Sometimes it is nice to be able to see what you are typing when the computer keeps telling you the passwords do not match. Here the ToolTip exposes the value of the PasswordBox.Password property to the user.
Let’s have a look at the XAML mark-up that was used to render this ToolTip. This XAML is not located in a resource, but is in-line with the PasswordBox control XAML. The blue lines of code will be commented on below.
VerticalAlignment=”Top”
Grid.Column=”1″ Grid.Row=”2″
d:LayoutOverrides=”VerticalAlignment”
Margin=”0,0,0,10″ Grid.RowSpan=”1″>
<PasswordBox.ToolTip>
<ToolTip DataContext=”{Binding Path=PlacementTarget,
RelativeSource={x:Static RelativeSource.Self}}”>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width=”Auto”/>
<ColumnDefinition Width=”*”/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height=”Auto”/>
<RowDefinition Height=”Auto”/>
<RowDefinition Height=”Auto”/>
</Grid.RowDefinitions>
<Border HorizontalAlignment=”Stretch”
BorderThickness=”0,0,0,1″
BorderBrush=”Black” Margin=”5″
Grid.Column=”0″ Grid.Row=”0″
Grid.ColumnSpan=”2″>
<TextBlock FontSize=”14″>
Two Password Data Bound Properties</TextBlock>
</Border>
<TextBlock Grid.Column=”0″
Grid.Row=”1″
Margin=”10,0,5,0″>
PasswordBox.Password is:</TextBlock>
<TextBlock Grid.Column=”1″
Grid.Row=”1″
FontWeight=”Bold”
Text=”{Binding Path=Password}”/>
<TextBlock Grid.Column=”0″
Grid.Row=”2″
Margin=”10,0,5,0″>
PasswordBox.ActualWidth is:</TextBlock>
<TextBlock Grid.Column=”1″
Grid.Row=”2″
FontWeight=”Bold”
Text=”{Binding Path=ActualWidth}”/>
</Grid>
</ToolTip>
</PasswordBox.ToolTip>
</PasswordBox>
This code is the same code used in the previous example with a few outer container changes. You will typically see most fancy ToolTips coded as resources to promote code reuse. However, you may find situations were placing the ToolTip XAML in with the control’s mark-up makes the most sense.
VisualBrush ToolTip Demo (The Big Kahuna)
Now it’s time for some fun. Use your mouse and resize the application and make it taller. Notice how the image size grows and shrinks as you resize the form. You have probably already seen it, but go ahead and place you mouse over the Window and you’ll see the cool ToolTip popup. I wrote this ToolTip for my applications that use the TabControl that allows the user to have many screens open at once. I wanted the ToolTip to resemble the ToolTip that the Vista TaskBar displays. This is more for show, but it does look cool in a production business application.
What is going on here, is a rectangle is painted with a VisualBrush that is the visual from the Window Grid contents. That rectangle is then surrounded with a border and a TextBox is placed above the border. It took me about an hour of playing around with all the settings to get it to look like this.
This ToolTip is create in code. The code is in the Window1.xaml.vb file. You can simply copy the CreateToolTipForTabItem function right into your own code and use it. I have marked several TODO’s in the code and provided suggestions for using this in your own code. Here is how that function is called and the ToolTip created:
This code snippet shows how to assign a ToolTip created in code to an objects ToolTip property. In this case, it is the Window. We create a New VisualBrush by down casting the Grid as a UIElement and pass this into the VisualBrush’s constructor. The second parameter is the title string that appears above the ToolTip visual.
Now, go ahead and resize the Window again and cause the ToolTip to reopen again. Um. Make the Window small, open the ToolTip, now make is large and open the ToolTip. What is going on here, is the visual from the Grid contents is painted on a 300 x 225 rectangle. When the Window is small, the contents are scaled to fill the ToolTip. For most business applications this scaling is not an issue since the forms are typically larger than 300 x 225. You can also adjust anything about this solution to suit your needs.
This example ToolTip is a good example of what it takes to create a small form in code as opposed to XAML. By the way, this ToolTip can also be created in XAML, I just wanted to demonstrate several methods for creating ToolTips.
Resources: I am the original author for all this code.
Source Code: After downloading the source code you MUST change the file extension from .zip.DOC to .zip. This is a requirment of WordPress.com.
Hope you can learn just a little bit more about WPF from this article and the Sample Series.
Just a grain of sand on the worlds beaches.






