WPF Add tooltip to track slider

I added a tooltip (shown below) to the track in the slider template, but instead of snapping to the current slider value, I would like to bind the value corresponding to the “track value” that the mouse is over. Similar to what the YouTube video slider allows. Thus, the user can hover over the track and also see the corresponding value without actually moving the thumb.

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

Any ideas? Thanks!

+3
source share
3 answers

, Track MouseMove, . Prefix, , :

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);
    }
}

<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>

:

enter image description here

+1

, , . mousein/out mousemove, .

, - , " ", , ..

0

    <Slider VerticalAlignment="Center" HorizontalAlignment="Stretch">
        <Slider.Template>
            <ControlTemplate TargetType="{x:Type Slider}">
                <Grid>
                    <xamlTest:ReflectablePopup x:Name="InfoPopup" Width="Auto" Height="Auto" PlacementTarget="{Binding ElementName=Thumb}" Placement="Top" StaysOpen="False" IsOpen="False" AllowsTransparency="True">
                        <Border Padding="2" CornerRadius="3" Background="#555C5C5C">
                            <Label Content="Your Text"></Label>
                        </Border>
                    </xamlTest:ReflectablePopup>
                    <Track x:Name="PART_Track">
                        <Track.Thumb>
                            <Thumb x:Name="Thumb" Width="10" Height="20">
                            </Thumb>
                        </Track.Thumb>
                    </Track>
                </Grid>
                <ControlTemplate.Triggers>
                    <Trigger SourceName="Thumb" Property="IsDragging" Value="True">
                        <Setter Value="True" TargetName="InfoPopup" Property="IsOpen" />
                    </Trigger>
                    <Trigger SourceName="Thumb" Property="IsDragging" Value="False">
                        <Setter Value="False" TargetName="InfoPopup" Property="IsOpen" />
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Slider.Template>
    </Slider>

As you can see, I am using ReflectablePopup instead of Popup. Because Popup cannot move after moving PlacementTarget .

Below is the fo ReflectablePopup (C #) code:

public class ReflectablePopup : Popup
{
    protected override void OnOpened(EventArgs e)
    {
        var friend = this.PlacementTarget;
        friend.QueryCursor += friend_QueryCursor;

        base.OnOpened(e);
    }

    protected override void OnClosed(EventArgs e)
    {
        var friend = this.PlacementTarget;
        friend.QueryCursor -= friend_QueryCursor;

        base.OnClosed(e);
    }

    private void friend_QueryCursor(object sender, System.Windows.Input.QueryCursorEventArgs e)
    {
        this.HorizontalOffset += +0.1;
        this.HorizontalOffset += -0.1;
    }
}
0
source

Source: https://habr.com/ru/post/1713455/


All Articles