【问题标题】:Slider Thumb with TextBlock in WPFWPF中带有TextBlock的滑块拇指
【发布时间】:2021-09-10 19:51:41
【问题描述】:

我是 WPF 新手,刚刚学习它。我正在尝试在 WPF 中制作自定义滑块。我想得到这样的结果:
。 但我明白了:
。 我的滑块样式如下所示:

<Style x:Key="Style_SliderLeftButton"
       TargetType="{x:Type RepeatButton}">
    <Style.Setters>
        <Setter Property="SnapsToDevicePixels"
                Value="True" />
        <Setter Property="OverridesDefaultStyle"
                Value="True" />
        <Setter Property="IsTabStop"
                Value="False" />
        <Setter Property="Focusable"
                Value="False" />
        <Setter Property="Background"
                Value="{DynamicResource Brush_OnBackground_OnSurface_High}" />
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type RepeatButton}">
                    <Border Background="{TemplateBinding Background}"
                            Margin="8,0,-8,0"
                            CornerRadius="2"
                            Height="4" />
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style.Setters>
</Style>

<Style x:Key="Style_SliderRightButton"
       TargetType="{x:Type RepeatButton}">
    <Style.Setters>
        <Setter Property="SnapsToDevicePixels"
                Value="True" />
        <Setter Property="OverridesDefaultStyle"
                Value="True" />
        <Setter Property="IsTabStop"
                Value="False" />
        <Setter Property="Focusable"
                Value="False" />
        <Setter Property="Background"
                Value="Transparent" />
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type RepeatButton}">
                    <Border Background="{TemplateBinding Background}"
                            Margin="0,0,8,0"
                            CornerRadius="2"
                            Height="4" />
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style.Setters>
</Style>

<Style x:Key="Style_SliderThumb"
       TargetType="{x:Type Thumb}">
    <Style.Setters>
        <Setter Property="SnapsToDevicePixels"
                Value="True" />
        <Setter Property="OverridesDefaultStyle"
                Value="True" />
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type Thumb}">
                    <StackPanel Orientation="Vertical">
                        <Grid>
                            <!-- Big point -->
                            <Ellipse Panel.ZIndex="0"
                                     Fill="{DynamicResource Brush_Primary}"
                                     StrokeThickness="0"
                                     Height="22"
                                     Width="22" />

                            <!-- Center point -->
                            <Ellipse Panel.ZIndex="1"
                                     Fill="{DynamicResource Brush_Background_Surface}"
                                     StrokeThickness="0"
                                     Height="6"
                                     Width="6" />

                            <Ellipse Panel.ZIndex="2"
                                     Fill="{DynamicResource Brush_Background_Primary}"
                                     StrokeThickness="0"
                                     Height="6"
                                     Width="6" />

                            <Ellipse Panel.ZIndex="3"
                                     Fill="{DynamicResource Brush_Surface_Overlay_08dp}"
                                     StrokeThickness="0"
                                     Height="6"
                                     Width="6" />

                        </Grid>
                        <TextBlock Text="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Slider}, Path=Value}"
                                   FontSize="14"
                                   FontWeight="SemiBold"
                                   FontFamily="{DynamicResource Font_Montserrat}"
                                   Foreground="{DynamicResource Brush_OnBackground_OnSurface_High}"
                                   Background="Transparent"
                                   TextAlignment="Center"
                                   Margin="0,7,0,0"
                                   HorizontalAlignment="Center"
                                   VerticalAlignment="Top" />
                    </StackPanel>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style.Setters>
</Style>

<!--Template when the orientation of the Slider is Horizontal.-->
<ControlTemplate x:Key="HorizontalSlider"
                 TargetType="{x:Type Slider}">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto"
                           MinHeight="{TemplateBinding MinHeight}" />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>

        <TickBar x:Name="TopTick"
                 SnapsToDevicePixels="True"
                 Placement="Top"
                 Height="4"
                 Visibility="Collapsed"
                 Fill="{DynamicResource Brush_OnBackground_OnSurface_Medium}" />

        <Border x:Name="TrackBackground"
                Margin="8,0"
                CornerRadius="2"
                Height="4"
                Grid.Row="1"
                BorderThickness="0"
                Background="{DynamicResource Brush_OnBackground_OnSurface_Medium}" />

        <Track Grid.Row="1"
               x:Name="PART_Track">

            <Track.DecreaseRepeatButton>
                <RepeatButton Style="{StaticResource Style_SliderLeftButton}"
                              Command="Slider.DecreaseLarge" />
            </Track.DecreaseRepeatButton>

            <Track.Thumb>
                <Thumb Style="{StaticResource Style_SliderThumb}" />
            </Track.Thumb>

            <Track.IncreaseRepeatButton>
                <RepeatButton Style="{StaticResource Style_SliderRightButton}"
                              Command="Slider.IncreaseLarge" />
            </Track.IncreaseRepeatButton>
        </Track>

        <TickBar x:Name="BottomTick"
                 SnapsToDevicePixels="True"
                 Grid.Row="2"
                 Fill="{TemplateBinding Foreground}"
                 Placement="Bottom"
                 Height="4"
                 Visibility="Collapsed" />
    </Grid>

    <ControlTemplate.Triggers>
        <Trigger Property="TickPlacement"
                 Value="TopLeft">
            <Setter TargetName="TopTick"
                    Property="Visibility"
                    Value="Visible" />
        </Trigger>
        <Trigger Property="TickPlacement"
                 Value="BottomRight">
            <Setter TargetName="BottomTick"
                    Property="Visibility"
                    Value="Visible" />
        </Trigger>
        <Trigger Property="TickPlacement"
                 Value="Both">
            <Setter TargetName="TopTick"
                    Property="Visibility"
                    Value="Visible" />
            <Setter TargetName="BottomTick"
                    Property="Visibility"
                    Value="Visible" />
        </Trigger>
    </ControlTemplate.Triggers>
</ControlTemplate>

<!--Template when the orientation of the Slider is Vertical.-->
<ControlTemplate x:Key="VerticalSlider"
                 TargetType="{x:Type Slider}">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto" />
            <ColumnDefinition Width="Auto"
                              MinWidth="{TemplateBinding MinWidth}" />
            <ColumnDefinition Width="Auto" />
        </Grid.ColumnDefinitions>

        <TickBar x:Name="TopTick"
                 SnapsToDevicePixels="True"
                 Placement="Left"
                 Width="4"
                 Visibility="Collapsed"
                 Fill="{DynamicResource Brush_OnBackground_OnSurface_Medium}" />

        <Border x:Name="TrackBackground"
                Margin="0"
                CornerRadius="2"
                Width="4"
                Grid.Column="1"
                BorderThickness="1"
                Background="{DynamicResource Brush_OnBackground_OnSurface_Medium}" />
        
        <Track Grid.Column="1"
               x:Name="PART_Track">
            
            <Track.DecreaseRepeatButton>
                <RepeatButton Style="{StaticResource Style_SliderLeftButton}"
                              Command="Slider.DecreaseLarge" />
            </Track.DecreaseRepeatButton>
            
            <Track.Thumb>
                <Thumb Style="{StaticResource Style_SliderThumb}" />
            </Track.Thumb>
            
            <Track.IncreaseRepeatButton>
                <RepeatButton Style="{StaticResource Style_SliderRightButton}"
                              Command="Slider.IncreaseLarge" />
            </Track.IncreaseRepeatButton>
        </Track>
        
        <TickBar x:Name="BottomTick"
                 SnapsToDevicePixels="True"
                 Grid.Column="2"
                 Fill="{TemplateBinding Foreground}"
                 Placement="Right"
                 Width="4"
                 Visibility="Collapsed" />
    </Grid>
    <ControlTemplate.Triggers>
        <Trigger Property="TickPlacement"
                 Value="TopLeft">
            <Setter TargetName="TopTick"
                    Property="Visibility"
                    Value="Visible" />
        </Trigger>
        <Trigger Property="TickPlacement"
                 Value="BottomRight">
            <Setter TargetName="BottomTick"
                    Property="Visibility"
                    Value="Visible" />
        </Trigger>
        <Trigger Property="TickPlacement"
                 Value="Both">
            <Setter TargetName="TopTick"
                    Property="Visibility"
                    Value="Visible" />
            <Setter TargetName="BottomTick"
                    Property="Visibility"
                    Value="Visible" />
        </Trigger>
    </ControlTemplate.Triggers>
</ControlTemplate>

<Style TargetType="{x:Type Slider}">
    <Setter Property="SnapsToDevicePixels"
            Value="True" />
    <Setter Property="OverridesDefaultStyle"
            Value="True" />
    <Style.Triggers>
        <Trigger Property="Orientation"
                 Value="Horizontal">
            <!--<Setter Property="MinWidth"
                    Value="104" />
            <Setter Property="MinHeight"
                    Value="21" />-->
            <Setter Property="Template"
                    Value="{StaticResource HorizontalSlider}" />
        </Trigger>
        <Trigger Property="Orientation"
                 Value="Vertical">
            <!--<Setter Property="MinWidth"
                    Value="21" />
            <Setter Property="MinHeight"
                    Value="104" />-->
            <Setter Property="Template"
                    Value="{StaticResource VerticalSlider}" />
        </Trigger>
    </Style.Triggers>
</Style>

我从文档中获取了模板:https://docs.microsoft.com/en-us/dotnet/desktop/wpf/controls/slider-styles-and-templates?view=netframeworkdesktop-4.8。 我怎样才能达到预期的效果?

【问题讨论】:

  • 为了理解您的模板,您能否将这个模板使用的画笔资源添加到代码中。如果您可以提供一个示例 XAML 来显示您提供的屏幕截图,这也将非常有帮助。

标签: wpf xaml slider textblock


【解决方案1】:

您的拇指居中,要更改此设置,请将您的堆栈面板切换到网格。这将使文本与椭圆重叠。对文本进行渲染转换以在视觉上移动它。


<TextBlock>
    <TextBlock.RenderTransform>
        <TranslateTransform X="0" Y="-30" />
    </TextBlock.RenderTransform>
</TextBlock>

【讨论】:

    【解决方案2】:

    如果您的真正意图是与 Slider 一起显示当前值,则最好使用 Slider 的内置 ToolTip。可自定义如下:

    <Slider AutoToolTipPlacement="BottomRight">
        <Slider.Resources>
            <Style TargetType="{x:Type ToolTip}" BasedOn="{StaticResource {x:Type ToolTip}}">
                <Setter Property="BorderThickness" Value="0"/>
                <Setter Property="Background" Value="Transparent" />
                <Setter Property="TextElement.Foreground" Value="White"/>
                <Setter Property="TextElement.FontWeight" Value="SemiBold"/>
            </Style>
        </Slider.Resources>
    </Slider>
    

    【讨论】:

    • 如果我想始终显示滑块的值怎么办?
    • 没有始终显示内置工具提示的选项。回到你原来的问题,你可以将背景栏设置VerticalAlignment的垂直位置调整为顶部,将上边距调整为适当的值。或者 user8934733 的 hack 可能会奏效。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-28
    • 1970-01-01
    • 2011-02-10
    • 2020-09-08
    • 1970-01-01
    相关资源
    最近更新 更多