Click here to Skip to main content
13,139,569 members (50,198 online)
Click here to Skip to main content
Add your own
alternative version


45 bookmarked
Posted 14 May 2009

Quick and Dirty (but nice!) ToolTips via Markup Extensions

, 15 May 2009
Rate this:
Please Sign up or sign in to vote.
Discusses the implementation of a MarkupExtension that displays a rich ToolTip.


This short tutorial discusses the use of a simple markup extension as an alternative to WPF styles in order to display rich ToolTips. The markup extension provides the following functionality: 

  • Displays a nice looking ToolTip rather than just plain text.
  • Optionally looks up strings in a resource dictionary to simplify localization.
  • Optional title text.  
  • Very simple declaration.  

Let's have a look at a simple sample first (taken from NetDrives, which is open source, too, btw). Here’s a what a typical ToolTip declaration in XAML looks like:



  ToolTip="{ext:Info Title=ShareNameTitleToolTip, Body=ShareNameInfoToolTip}"


…and this is the output. As you can see, the markup expression not only displays a nicely formatted ToolTip, but also performed a lookup to resolve both the ToolTip's title and body text:



Let's walk through the necessary steps...

Step 1: Creating the Popup Control

The first step is to create a simple control that contains the ToolTip. Basically, this is a simple UserControl with the following features: 

  • A grid with two rows. The first row contains just the title and is auto-sized to make sure it collapses if the title is not used at all.
  • Two TextBlocks for title and body text.
  • An image (I didn’t make that one bindable, I always use the same one).
  • Two dependency properties that provide binding capabilities for header and body text.

Here’s what the control looks like in Blend:


Of course, you can already use this user control through styles and/or directly declared in XAML whenever you need:

<Image Source="..\Shared\Images\HelpSmall.png">
    <MyToolTipControl Header="My Title" Body="This is a ToolTip" />

However, this would still take a style to hide the ToolTip's border and you are lacking resource file lookups. The markup extension makes this way easier…

Step 2: Implementing the Markup Extension

MarkupExtension is one of the lesser known stars in WPF - it requires a little coding, but once in place, it greatly simplify things for you. A simple yet brilliant example is Dr. WPF’s ValueConverter extension, and I already blogged a few times about other useful applications.

This <code>Info markup extension basically provides the following:

  • Two properties (Title and Body)
  • Resource lookup with fallback mechanism (string is used directly if it’s not a resource key)
  • ToolTip creation


/// <span class="code-SummaryComment"><summary></span>
/// A markup extension that returns a
/// <span class="code-SummaryComment"><see cref="InfoPopup"/> control preconfigured</span>
/// with header and text information according to the
/// <span class="code-SummaryComment"><see cref="Title"/> and <see cref="Body"/></span>
/// properties.
/// <span class="code-SummaryComment"></summary></span>
public class Info : MarkupExtension
  /// <span class="code-SummaryComment"><summary></span>
  /// Either a title text or a resource key that can be used
  /// to look up the title.
  /// <span class="code-SummaryComment"></summary></span>
  public string Title { get; set; }

  /// <span class="code-SummaryComment"><summary></span>
  /// Either a tooltips' main text or a resource key that can be used
  /// to look up the text.
  /// <span class="code-SummaryComment"></summary></span>
  public string Body { get; set; }

  /// <span class="code-SummaryComment"><summary></span>
  /// Empty default constructor.
  /// <span class="code-SummaryComment"></summary></span>
  public Info()

  /// <span class="code-SummaryComment"><summary></span>
  /// Inits the <span class="code-SummaryComment"><see cref="Info"/> markup extension</span>
  /// with the title and body.
  /// <span class="code-SummaryComment"></summary></span>
  public Info(string title, string body)
    Title = title;
    Body = body;

  /// <span class="code-SummaryComment"><summary></span>
  /// Performs a lookup for the defined <span class="code-SummaryComment"><see cref="Title"/> and</span>
  /// <span class="code-SummaryComment"><see cref="Info"/> and creates the tooltip control.</span>
  /// <span class="code-SummaryComment"></summary></span>
  /// <span class="code-SummaryComment"><returns></span>
  /// A tooltip control.
  /// <span class="code-SummaryComment"></returns></span>
  public override object ProvideValue(IServiceProvider serviceProvider)
    //create the user control that 
    InfoPopup popup = new InfoPopup();

    if (!String.IsNullOrEmpty(Title))
      //look up title - if the string is not a
      //resource key, use it directly
      var result = Resources.ResourceManager.GetObject(Title) ?? Title;
      popup.HeaderText = (string)result;

    if (!String.IsNullOrEmpty(Body))
      //look up body text - if the string is not a
      //resource key, use it directly
      var result = Resources.ResourceManager.GetObject(Body) ?? Body;
      popup.BodyText = (string)result;

    //create tooltip and make sure only the content is visible
    ToolTip tt = new ToolTip();
    tt.HasDropShadow = false;
    tt.BorderThickness = new Thickness(0);
    tt.Background = Brushes.Transparent;
    tt.Content = popup;

    return tt;

Conclusion and Sample

This is only one of several ways to tackle the problem, but I really like that it only takes a single line to have a rich ToolTip in place. The implementation provided here may not completely suit your requirements, but it can easily be tailored to your needs.

The link below points to a sample project that contains both the markup extension and ToolTip control. Enjoy :-)



This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

Philipp Sumi
Architect I'm a gun for hire
Switzerland Switzerland
Philipp is an independent software engineer with great love for all things .NET.
He lives in Winterthur, Switzerland and his home on the web is at

You may also be interested in...


Comments and Discussions

Generalbindable image Pin
picazo14-Oct-09 9:28
memberpicazo14-Oct-09 9:28 
QuestionHello Philipp Pin
sinun24-May-09 23:55
membersinun24-May-09 23:55 
AnswerRe: Hello Philipp Pin
Philipp Sumi25-May-09 5:28
memberPhilipp Sumi25-May-09 5:28 
AnswerRe: Hello Philipp Pin
sinun26-May-09 20:20
membersinun26-May-09 20:20 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.170915.1 | Last Updated 16 May 2009
Article Copyright 2009 by Philipp Sumi
Everything else Copyright © CodeProject, 1999-2017
Layout: fixed | fluid