【问题标题】:Textblock over the elipse slider thumb - avoid resize of grid behind elipse when text is changing C# WPF椭圆滑块拇指上的文本块 - 避免在文本更改 C# WPF 时调整椭圆后面的网格大小
【发布时间】:2021-10-12 13:27:27
【问题描述】:

我想在椭圆滑块拇指的顶部使用滑块的实际值来实现文本块。当文本块的宽度与椭圆相同时,一切正常,但我需要增加文本块的宽度。

在 textloblock 的宽度改变后,椭圆的网格宽度也改变了,滑块看起来不再合适了。

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

  2. 文本块宽度大于椭圆宽度 texblock width higher

您知道如何避免图 2 中的情况吗?

滑块拇指样式:

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

编辑: 根据文本居中问题的完整代码。

主窗口:

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

滑块样式:

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

【问题讨论】:

    标签: c# wpf slider thumb


    【解决方案1】:

    您必须将TextBlock 包裹在Canvas 中以避免剪裁,并且您不需要为TextBLock 设置宽度以使其获得所需的大小。

    这是您的案例的有效代码:

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

    更新

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

    我已将TextBlock 包裹在Border 中,以使其具有边距。

    注意:我将TextBlockForeground颜色设置为黑色以进行测试。

    【讨论】:

    • 非常感谢!它工作得很好。如果你能提供帮助,我还有一个问题:如何使文本居中,而不是现在当它是像“100 mm”这样的长文本时,它从椭圆的正上方开始并向右环绕。我想把它放在中心。我尝试像这样(0,0,80,80)设置画布的边距并将画布的水平对齐更改为左,但似乎它是向左的最大值。
    • 好吧,我用很长的文本测试了我的代码,它应该居中,所以我建议确保Canvas的宽度绑定到valueTextBlock的实际宽度.
    • 我已经绑定了 Canvas 的宽度。你的文字有多长?对于像百分比值 (50 %) 这样的短文本也可以,但是对于像 (101.22 mm) 这样的长文本,它会向右移动。您是否也尝试过更长的文本?
    • 它工作正常,我刚刚试过你的值,这里是result。如果您愿意,请编辑您的问题并添加您的实际代码以便查看。
    • 好的,我已将完整代码放入已编辑的问题中。再次感谢您的游览帮助。
    猜你喜欢
    • 1970-01-01
    • 2021-12-29
    • 2023-03-20
    • 1970-01-01
    • 1970-01-01
    • 2015-05-18
    • 2017-07-20
    • 1970-01-01
    • 2012-10-02
    相关资源
    最近更新 更多