[英]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 的宽度发生变化后,椭圆的网格宽度也发生了变化,滑块看起来不再合适。
Picture of slider with textblock width = elipse width textblock width = elipse width文本块宽度 = 椭圆宽度文本块宽度 = 椭圆宽度的滑块图片
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.