Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WPF Adding a Tooltip to the Track of a Slider

I have added a tooltip (shown below) to the track in the slider template, but rather than binding to the current value of the slider, I would like to bind to the value corresponding to the "track value" the mouse is over. Similar to what the youtube video slider allows. So the user can mouseover the track and also see the corresponding value, without having to actually move the thumb.

<Track Grid.Row="1" Name="PART_Track" ToolTip="{Binding Path=Value}" ToolTipService.Placement="Mouse">
</Track>

Any ideas? Thanks!

like image 449
Sharun Avatar asked Oct 15 '22 14:10

Sharun


1 Answers

I have created an attached behaviour that will find the Track from a slider and subscribe to its MouseMove event to set the tooltip of the track to the corresponding value of the tick the mouse is over. I also added a Prefix property so you can write what the value is:

internal class ShowTickValueBehavior : Behavior<Slider>
{
    private Track track;

    public static readonly DependencyProperty PrefixProperty = DependencyProperty.Register(
        "Prefix",
        typeof(string),
        typeof(ShowTickValueBehavior),
        new PropertyMetadata(default(string)));

    public string Prefix
    {
        get
        {
            return (string)this.GetValue(PrefixProperty);
        }
        set
        {
            this.SetValue(PrefixProperty, value);
        }
    }

    protected override void OnAttached()
    {
        this.AssociatedObject.Loaded += this.AssociatedObjectOnLoaded;
        base.OnAttached();
    }

    protected override void OnDetaching()
    {
        this.track.MouseMove -= this.TrackOnMouseMove;
        this.track = null;
        base.OnDetaching();
    }

    private void AssociatedObjectOnLoaded(object sender, RoutedEventArgs routedEventArgs)
    {
        this.AssociatedObject.Loaded -= this.AssociatedObjectOnLoaded;
        this.track = (Track)this.AssociatedObject.Template.FindName("PART_Track", this.AssociatedObject);
        this.track.MouseMove += this.TrackOnMouseMove;
    }

    private void TrackOnMouseMove(object sender, MouseEventArgs mouseEventArgs)
    {
        var position = mouseEventArgs.GetPosition(this.track);
        var valueFromPoint = this.track.ValueFromPoint(position);
        var floorOfValueFromPoint = (int)Math.Floor(valueFromPoint);
        var toolTip = string.Format(CultureInfo.InvariantCulture, "{0}{1}", this.Prefix, floorOfValueFromPoint);

        ToolTipService.SetToolTip(this.track, toolTip);
    }
}

Usage

<Window x:Class="TestSlider.MainView"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-TestSlider"
    xmlns:system="clr-namespace:System;assembly=mscorlib"
    xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
    >
    <Grid>
        <Slider Name="Slider1"
                IsSnapToTickEnabled="True"
                TickFrequency="1"
                TickPlacement="BottomRight"
                IsMoveToPointEnabled="True"
                Minimum="13"
                Maximum="25"
                >
                <i:Interaction.Behaviors>
                    <local:ShowTickValueBehavior Prefix="Volume: "/>
                </i:Interaction.Behaviors>
        </Slider>
    </Grid>

Result:

enter image description here

like image 120
JoanComasFdz Avatar answered Oct 19 '22 04:10

JoanComasFdz