Modifying the auto tooltip of a Slider

This blog post answers a question on the WPF Forum which asks how to programmatically affect the text in a Slider’s auto tooltip.

Slider has a nice feature where it displays an “auto tooltip” as the user slides the thumb.  The tooltip displays the current value of the Slider, and it follows the thumb as the user slides it back and forth.  Slider exposes two properties that allow you to affect the auto tooltip, AutoToolTipPlacement and AutoToolTipPrecision.  The latter allows you to affect how accurate the tooltip’s text is, relative to the Slider’s value.  What is not possible, however, is to modify the text in the auto tooltip.  This blog post shows one workaround for that problem.

I tried to gain access to the auto tooltip in many ways, but none succeeded. As a last resort, I decided to use a little reflection to gain access to the _autoToolTip field in Slider.  After poking around in Reflector I realized that the auto tooltip’s content is only updated in two virtual methods: OnThumbDragStarted and OnThumbDragDelta.  Armed with that information it was trivial to create a Slider subclass which makes it possible to format the auto tooltip’s display text.

FormattedSlider (class)

Using the FormattedSlider is simply a matter of setting its AutoToolTipFormat property to a format string, as seen below:

FormattedSlider (usage)

The demo application looks like this when you run it:

FormattedSlider (screenshot)

Using a format string to modify the tooltip text is just one option.  If you have more involved needs than just wrapping the Slider’s value in some text, you might want to change the AutoToolTipFormat property to a dependency property named something like AutoToolTipContent, which could then be set via triggers.

Download the demo project here: FormattedSlider (demo project)  Be sure to change the extension from .DOC to .ZIP and then decompress it.

7 Responses to Modifying the auto tooltip of a Slider

  1. David says:

    Hey Josh,

    Noob here. I’m trying to use your example to get a float formatted. Values range between 0 and 1. What am I doing wrong?

    <local:FormattedSlider
    x:Name=”slider1″
    AutoToolTipFormat=”{}mua = {0:#.##}/mm”
    AutoToolTipPlacement=”BottomRight”
    TickPlacement=”BottomRight”
    SmallChange=”0.01″ LargeChange=”0.10″
    Minimum=”0.00″ Maximum=”1.00″
    TickFrequency=”0.10″
    />
    <Label Height=”23″ Name=”label1″ Width=”275″ HorizontalAlignment=”Center” HorizontalContentAlignment=”Center”
    Content=”{Binding ElementName=slider1, Path=Value}”/>

    Could only get it to work with: AutoToolTipPrecision=”2″

    …but that avoids the formatting altogether (AutoToolTipPrecision=”5″ seems to ignore the string.Format()).

    What to do?

  2. Josh Smith says:

    David,

    There are several things wrong with your approach, but what you want to achieve is possible. Basically the fundamental issue here is that the auto tooltip’s Content is a string, not a numeric value. So you need to convert the content to a number if you want to apply floating point formatting to it. Here’s the method which must be changed in FormattedSlider to do this:

    private void FormatAutoToolTipContent()
    {
    if (string.IsNullOrEmpty(this.AutoToolTipFormat))
    return;

    object content;

    string text = this.AutoToolTip.Content as string;
    double number;
    if (double.TryParse(text, out number))
    {
    content = number;
    }
    else
    {
    content = text;
    }

    this.AutoToolTip.Content = string.Format(
    this.AutoToolTipFormat,
    content);
    }

    Since your format string does not start with a curly brace ({) you don’t need to begin with the XAML escape sequence ({}). Also, the format string you used can be replaced with {0:F2}

    Josh

  3. David says:

    Josh,

    I’ve learned a couple new things here. Thanks for the solution. Works great. Somewhere under the hood does the slider have a private numeric field/property? Seems like a work-around to convert it “back.” This isn’t a performance issue for me, just curious.

    Thanks again,
    David

  4. Josh Smith says:

    David,

    Reflector is your friend. 😉

    Josh

  5. w0lfshad3 says:

    Hi, another newb here :), if i had an enum like this:
    enum test
    {
    zero, one, two, three, four, five, six, seven, eight, nine, ten, eleven, twelve, thirteen, fourteen, fifteen, sixteen, seventeen, eighteen, nineteen, twenty
    }
    How would i display the string instead of the integer in autotooltip?

  6. w0lfshad3 says:

    found out how:
    This was a problem of cast:
    this.AutoToolTip.Content = (test)Convert.ToInt32(this.AutoToolTip.Content);

    test is my enum with one, two, three etc

  7. w0lfshad3 says:

    has a flaw though, first time i click the slider’s bar only one char wide tooltip appears, how can i change that?