我正在为一个滑块创建一个自定义的TickBar。这个CustomTickBar允许我在滑块上放置不同的标记。我将使用以下模型:
Interface IModel
{
string Id;
}
Class Model1 : IModel
{
string Id;
string SomeProperty;
}
Class Model2 : IModel
{
string Id;
string SomeOtherProperty;
}这个想法是,我为这个TickBar控件提供了一个List<IModel>,根据IModel的类型,标记图标将会改变;例如,对于Model1,它将是一个三角形,而对于Model2,它将是一个矩形。我知道这是可以使用DataTemplate的。但是WPF TickBar没有DataTemplate属性。现在有没有一种方法可以使用DataTemplate属性并子类化TickBar来做到这一点呢?
注意:我知道我可以使用OnRender()创建自定义tick,但我正在尝试检查是否有一种方法可以通过编写尽可能少的代码隐藏来做到这一点。
发布于 2018-03-22 20:31:04
TickBar没有默认样式,所以看起来使用OnRender是他们设计它的方式。
我正在考虑的另一个解决方案是:
TickBar设置自己的样式,甚至可以基于某些模型数据设置样式。使用themes/generic.xaml和以下代码为控件应用自定义样式:
static void MyCustomTickBar() {
DefaultStyleKeyProperty.OverrideMetadata(typeof(MyCustomTickBar), new FrameworkPropertyMetadata(typeof(MyCustomTickBar)));
}Slider的模板并使用新的TickBar,而不是内置的。Here是滑块的默认模板。我使用style snooper来提取它。很抱歉,我无法在我的答案中提供它,它太长了。
发布于 2018-03-26 06:28:32
首先尝试为滑块创建一个样式。例如,就像这样:
<Window.Resources>
<SolidColorBrush x:Key="HorizontalSliderTrackNormalBackground" Color="#FFE7EAEA"/>
<LinearGradientBrush x:Key="HorizontalSliderTrackNormalBorder" EndPoint="0,1" StartPoint="0,0">
<GradientStop Color="#FFAEB1AF" Offset="0.1"/>
<GradientStop Color="#FFAEB1AF" Offset=".9"/>
</LinearGradientBrush>
<Style x:Key="SliderRepeatButtonStyle" TargetType="{x:Type RepeatButton}">
<Setter Property="OverridesDefaultStyle" Value="true"/>
<Setter Property="IsTabStop" Value="false"/>
<Setter Property="Focusable" Value="false"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type RepeatButton}">
<Rectangle Fill="Transparent"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="CustomThumbForSlider" TargetType="{x:Type Thumb}">
<Setter Property="OverridesDefaultStyle" Value="True"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Thumb}">
<Ellipse Fill="#009EFF" Stroke="#009EFF" Height="14" Width="14"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="MyCustomStyleForSlider" TargetType="{x:Type Slider}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Slider}">
<Border Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition Height="Auto" MinHeight="{TemplateBinding MinHeight}"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TickBar x:Name="TopTick" Visibility="Collapsed" Fill="{TemplateBinding Foreground}" Placement="Top" Height="10" Grid.Row="2"/>
<TickBar x:Name="BottomTick" Visibility="Collapsed" Fill="{TemplateBinding Foreground}" Placement="Bottom" Height="10" Grid.Row="2"/>
<Border x:Name="TrackBackground"
Background="{StaticResource HorizontalSliderTrackNormalBackground}"
BorderBrush="{StaticResource HorizontalSliderTrackNormalBorder}"
BorderThickness="2" CornerRadius="1"
Margin="5,0" VerticalAlignment="Center" Height="10.0" Grid.Row="1" >
<Canvas Margin="-6,-2">
<Rectangle Visibility="Hidden" x:Name="PART_SelectionRange" Height="6.0"
Fill="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"
Stroke="{DynamicResource {x:Static SystemColors.ControlDarkDarkBrushKey}}"
StrokeThickness="2.0"/>
</Canvas>
</Border>
<Track x:Name="PART_Track" Grid.Row="1" >
<Track.DecreaseRepeatButton>
<RepeatButton Style="{StaticResource SliderRepeatButtonStyle}" Command="{x:Static Slider.DecreaseLarge}"/>
</Track.DecreaseRepeatButton>
<Track.IncreaseRepeatButton>
<RepeatButton Style="{StaticResource SliderRepeatButtonStyle}" Command="{x:Static Slider.IncreaseLarge}"/>
</Track.IncreaseRepeatButton>
<Track.Thumb>
<Thumb x:Name="Thumb" Style="{StaticResource CustomThumbForSlider}" Background="Black"/>
</Track.Thumb>
</Track>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>然后,您可以定义使用以下样式的Slider:
<Slider Name="CustomSlider" Style="{StaticResource MyCustomStyleForSlider}"/>为了根据某些属性更改样式,您可以添加一个数据触发器。只需用新样式替换现有样式:
<Style x:Key="CustomThumbForSlider" TargetType="{x:Type Thumb}">
<Setter Property="OverridesDefaultStyle" Value="True"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Thumb}">
<Ellipse Fill="#009EFF" Stroke="#009EFF" Height="14" Width="14"/>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<DataTrigger Binding="{Binding Path=IsDifferent}" Value="True">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Thumb}">
<Ellipse Fill="#009055" Stroke="#009055" Height="14" Width="14"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</DataTrigger>
</Style.Triggers>
</Style>当slider的datacontext对于属性"IsDifferent“有不同的值时,这个新样式将改变外观。
<Slider Name="CustomSlider" Style="{StaticResource MyCustomStyleForSlider}" DataContext="{Binding Path=MyContext}"/>当然,也可以根据您的喜好用不同的形状替换绿色椭圆,也可以使用不同的属性。
对于模板问题,通常最好使用ControlTemplate,或者使用ContentControl,它的DataTemplate可以自由设置,并且将充当您自己控件的父控件。
发布于 2018-03-22 18:48:15
我最近自己也尝试过覆盖一个自定义滑块的onrender,这很棘手。我不会走那条路的。我建议您考虑添加另一个控件来保持标记,并使其与滑块的高度或宽度相匹配。如果你的“滴答”是固定的,那么这可能只是一个包含路径的统一网格,你可以使用资源来定义他们的数据,使用DynamicResource几何图形。您可以通过合并不同的几何图形或为其创建数据模板来切换几何图形。
https://stackoverflow.com/questions/49216851
复制相似问题