简体   繁体   English

椭圆滑块拇指上的文本块 - 避免在文本更改 C# WPF 时调整椭圆后面的网格大小

[英]Textblock over the elipse slider thumb - avoid resize of grid behind elipse when text is changing C# WPF

I would like to implement textblock with actual value of slider on the top of elipse slider thumb.我想在椭圆滑块拇指顶部使用滑块的实际值来实现文本块。 When textblock have the same widht as elipse everything is working properly but I need to increase the width of textblock.当 textblock 与 elipse 具有相同的宽度时,一切正常,但我需要增加 textblock 的宽度。

After width of textloblock changes also width of grid for elipse changed and slider is not looking proper anymore.在 textloblock 的宽度发生变化后,椭圆的网格宽度也发生了变化,滑块看起来不再合适。

  1. Picture of slider with textblock width = elipse width textblock width = elipse width文本块宽度 = 椭圆宽度文本块宽度 = 椭圆宽度的滑块图片

  2. Textblock width higher than elipse width texblock width higher文本块宽度高于椭圆宽度文本块宽度更高

Do you have any idea how to avoid situation from picture 2?您知道如何避免图 2 中的情况吗?

Slider thumb style:滑块拇指样式:

            <Thumb x:Name="SliderThumb">
               <Thumb.Style>
                 <Style  TargetType="Thumb">
                   <Setter Property="SnapsToDevicePixels" Value="true" />
                   <Setter Property="OverridesDefaultStyle" Value="true" />
                   <Setter Property="Template">
                     <Setter.Value>
                       <ControlTemplate  TargetType="Thumb">
                         <Grid  Background="Transparent">
                           <Ellipse VerticalAlignment="Center"  HorizontalAlignment="Center" Fill="Blue" Height="30" Width="30"/>
                           <TextBlock  Width="60" TextAlignment="Center" VerticalAlignment="Center" Margin="0,0,0,80"
                            HorizontalAlignment="Center" Background="Transparent" Foreground="Black" FontSize="24" 
                            Text="{Binding Value, RelativeSource={RelativeSource AncestorType={x:Type Slider}}}"/>
                         </Grid>
                     </ControlTemplate>
                   </Setter.Value>
                 </Setter>
              </Style>
            </Thumb.Style>
          </Thumb>

EDIT: Full code according to issue with text centering.编辑:根据文本居中问题的完整代码。

MainWindow:主窗口:

 <Grid>
    <ContentControl   Height="70" Width="400">
       <Slider x:Name="slider2"  IsMoveToPointEnabled="True" Tag="mm" Maximum="210"  Width="300" VerticalAlignment="Bottom" Grid.Row="0" Style="{StaticResource Horizontal_Slider}"/>
    </ContentControl> 
</Grid>

Slider style:滑块样式:

 <Style x:Key="SliderRepeatButton" TargetType="RepeatButton"> <Setter Property="SnapsToDevicePixels" Value="true" /> <Setter Property="OverridesDefaultStyle" Value="true" /> <Setter Property="IsTabStop" Value="false" /> <Setter Property="Focusable" Value="false" /> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="RepeatButton"> <Border Height="10" Background="Red"/> </ControlTemplate> </Setter.Value> </Setter> </Style> <Style x:Key="SliderRepeatButton1" TargetType="RepeatButton"> <Setter Property="SnapsToDevicePixels" Value="true" /> <Setter Property="OverridesDefaultStyle" Value="true" /> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="RepeatButton"> <Border Height="10" Background="Blue" SnapsToDevicePixels="True" /> </ControlTemplate> </Setter.Value> </Setter> </Style> <Style x:Key="SliderThumb" TargetType="Thumb"> <Setter Property="SnapsToDevicePixels" Value="true" /> <Setter Property="OverridesDefaultStyle" Value="true" /> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="Thumb"> <Grid MaxWidth="{Binding ElementName=ellipseThumb, Path=ActualWidth}" Background="Transparent"> <Ellipse x:Name="ellipseThumb" Fill="Blue" Height="30"Width="30"/> <Canvas Margin="0,0,0,100" ClipToBounds="False" Height="{Binding ElementName=valueTextBlock, Path=ActualHeight}" Width="{Binding ElementName=valueTextBlock, Path=ActualWidth}"> <TextBlock Background="Transparent" Foreground="{TemplateBinding Background}" FontSize="24"> <Run Text="{Binding Value,StringFormat={}{0:F2}, RelativeSource={RelativeSource AncestorType={x:Type Slider}}}"/> <Run Text="{Binding Tag, RelativeSource={RelativeSource AncestorType={x:Type Slider}}}"/> </TextBlock> </Canvas> </Grid> </ControlTemplate> </Setter.Value> </Setter> </Style> <ControlTemplate x:Key="CustomSlider" TargetType="Slider"> <Grid> <Grid.RowDefinitions> <RowDefinition Height="Auto" /> <RowDefinition Height="Auto" MinHeight="{TemplateBinding MinHeight}" /> <RowDefinition Height="Auto" /> </Grid.RowDefinitions> <Track Grid.Row="1" x:Name="PART_Track" > <Track.DecreaseRepeatButton> <RepeatButton x:Name="DecreaseSlider" Style="{StaticResource SliderRepeatButton1}" Command="Slider.DecreaseLarge" /> </Track.DecreaseRepeatButton> <Track.Thumb> <Thumb x:Name="SliderThumb" Style="{StaticResource SliderThumb}" /> </Track.Thumb> <Track.IncreaseRepeatButton> <RepeatButton x:Name="IncreaseSlider" Style="{StaticResource SliderRepeatButton}" Command="Slider.IncreaseLarge" /> </Track.IncreaseRepeatButton> </Track> </Grid> </ControlTemplate> <Style x:Key="Horizontal_Slider" TargetType="Slider"> <Setter Property="Focusable" Value="False"/> <Setter Property="SnapsToDevicePixels" Value="true" /> <Setter Property="OverridesDefaultStyle" Value="true" /> <Style.Triggers> <Trigger Property="Orientation" Value="Horizontal"> <Setter Property="MinHeight" Value="21" /> <Setter Property="MinWidth" Value="104" /> <Setter Property="Template" Value="{StaticResource CustomSlider}" /> </Trigger> </Style.Triggers> </Style>

You have to wrap your TextBlock in a Canvas to avoid clipping, and also you need to not set the width for TextBLock to let it get the size it need.您必须将TextBlock包裹在Canvas以避免剪切,而且您不需要设置TextBLock的宽度以使其获得所需的大小。

Here is a working code for your case:这是您案例的工作代码:

<Thumb x:Name="SliderThumb">
    <Thumb.Style>
        <Style  TargetType="Thumb">
            <Setter Property="SnapsToDevicePixels" Value="true" />
            <Setter Property="OverridesDefaultStyle" Value="true" />
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="Thumb">
                        <Grid Background="Transparent" MaxWidth="{Binding ElementName=ellipse, Path=ActualWidth}">
                            <Ellipse x:Name="ellipse" VerticalAlignment="Center" HorizontalAlignment="Center" Fill="Blue" Height="30" Width="30"/>
                            <Canvas Margin="0,0,0,80"
                                    Height="{Binding ElementName=valueTextBlock, Path=ActualHeight}"
                                    Width="{Binding ElementName=valueTextBlock, Path=ActualWidth}"
                                    HorizontalAlignment="Center">
                                <TextBlock x:Name="valueTextBlock"
                                           Background="Transparent"
                                           Foreground="Black"
                                           FontSize="24"
                                           Text="{Binding Value, RelativeSource={RelativeSource AncestorType={x:Type Slider}}}"/>
                            </Canvas>
                        </Grid>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </Thumb.Style>
</Thumb>

Update更新

Here is a better style for Thumb with better alignment这是一个更好的Thumb样式,具有更好的对齐方式

<Style x:Key="SliderThumb" TargetType="Thumb">
    <Setter Property="SnapsToDevicePixels" Value="true" />
    <Setter Property="OverridesDefaultStyle" Value="true" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="Thumb">
                <Grid MaxWidth="{Binding ElementName=ellipseThumb, Path=ActualWidth}"
                      MaxHeight="{Binding ElementName=ellipseThumb, Path=ActualHeight}"
                      Background="Transparent">
                    <Grid.RowDefinitions>
                        <RowDefinition Height="0"/>
                        <RowDefinition/>
                    </Grid.RowDefinitions>
                    <Ellipse x:Name="ellipseThumb" Fill="Blue" Height="30" Width="30" Grid.Row="1"/>
                    <Canvas Grid.Row="0"
                            Height="{Binding ElementName=valueBorder, Path=ActualHeight}"
                            Width="{Binding ElementName=valueBorder, Path=ActualWidth}"
                            HorizontalAlignment="Center"
                            VerticalAlignment="Bottom">
                        <Border x:Name="valueBorder">
                            <TextBlock Margin="0,0,0,5"
                                       Background="Transparent"
                                       Foreground="Black"
                                       FontSize="24">
                                <Run Text="{Binding Value,StringFormat={}{0:F2}, RelativeSource={RelativeSource AncestorType={x:Type Slider}}}"/>
                                <Run Text="{Binding Tag, RelativeSource={RelativeSource AncestorType={x:Type Slider}}}"/>
                            </TextBlock>
                        </Border>
                    </Canvas>
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

I have wrapped the TextBlock inside a Border to allow it to have margin.我将TextBlock包裹在Border以允许它有边距。

Note: I set Foreground color of TextBlock to Black for testing purpose.注意:为了测试目的,我将TextBlock Foreground设置为黑色。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM