WPF将工具提示添加到滑块轨道

时间:2009-07-24 14:40:29

标签: wpf tooltip slider

我在滑块模板的轨道上添加了一个工具提示(如下所示),但不是绑定到滑块的当前值,我想绑定到对应于“轨道值”的值,鼠标是过度。与youtube视频滑块允许的类似。因此,用户可以鼠标悬停在轨道上并且还可以看到相应的值,而无需实际移动拇指。

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

有什么想法吗?谢谢!

3 个答案:

答案 0 :(得分:2)

我创建了一个附加行为,它将从滑块中找到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 :(得分:0)

我想你将不得不创建一个新的控件,继承自滑块。您需要实现mousein / out和mousemove,根据鼠标偏移计算值并更改工具提示。

我不认为你可以“开箱即用”使用任何属性,所以如果你需要考虑重新调整边距等,计算可能会相当棘手。

答案 2 :(得分:0)

首先你需要修改Slider控件

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

如您所见,我使用ReflectablePopup而不是Popup。因为Popup在 PlacementTarget 移动后无法重新定位。

在ReflectablePopup(C#)的代码下面:

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