我有一些视觉元素的定义,我想用于两个不同的控件(Button,Thumb)。有没有办法摆脱重复的代码?
<Style x:Key="HorizontalSliderThumbStyle" TargetType="{x:Type Thumb}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Thumb}">
this block is the same --> <Grid>
<VisualStateManager.VisualStateGroups>
...
</VisualStateManager.VisualStateGroups>
<Rectangle x:Name="borderRect" Fill="{TemplateBinding BorderBrush}" />
...
<Style x:Key="KeyboardButtonStyle" TargetType="{x:Type Button}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
this block is the same --> <Grid>
<VisualStateManager.VisualStateGroups>
...
</VisualStateManager.VisualStateGroups>
<Rectangle x:Name="borderRect" Fill="{TemplateBinding BorderBrush}" />
...
答案 0 :(得分:2)
你可以这样做:
<ControlTemplate TargetType="{x:Type Control}" x:Key="SharedControlTemplate">
<Grid>
<Rectangle Fill="{TemplateBinding BorderBrush}"/>
<TextBlock Text="Shared Control Template"/>
</Grid>
</ControlTemplate>
<Style TargetType="{x:Type Thumb}" x:Key="HorizontalSliderThumbStyle">
<Setter Property="Template" Value="{StaticResource SharedControlTemplate}"/>
</Style>
<Style TargetType="{x:Type Button}" x:Key="KeyboardButtonStyle">
<Setter Property="Template" Value="{StaticResource SharedControlTemplate}"/>
</Style>
Thumb
和Button
都来自Control
的基类(不是立即,而是它的祖先之一)。因此,如果为其定义ControlTemplate
,则可以为两个控件提供相同的模板。然后,按照风格,你将根据自己的需要量身定制自己的行为。
使用示例:
<Thumb Style="{StaticResource HorizontalSliderThumbStyle}" BorderBrush="AliceBlue"/>
<Button Style="{StaticResource KeyboardButtonStyle}" BorderBrush="Aquamarine"/>
修改强>
在评论中,您提到要在ContentPresenter
中使用ControlTemplate
。您必须绑定到Content
的{{1}}属性。由于并非每个ContentControl
都是Control
,因此它仅适用于包含实际内容的ContentControl
...但如果它没有内容,则不会发生任何错误。这是改变:
Controls
请注意,我为<ControlTemplate TargetType="{x:Type Control}" x:Key="SharedControlTemplate">
<Grid>
<Rectangle Fill="{TemplateBinding BorderBrush}"/>
<TextBlock Text="Shared Control Template"/>
<ContentPresenter Content="{TemplateBinding ContentControl.Content}"/>
</Grid>
</ControlTemplate>
添加了一行,以绑定ContentPresenter
的内容。如果您想添加某种内容,它会接受它:
ContentControl
答案 1 :(得分:0)
您应该可以使用DataTemplate
来定义内部控件,然后使用ContentControl
Class在每个ControlTemplate
中呈现它们。试试这个:
在Resources
:
<DataTemplate x:Key="InnerContent">
<!-- Define your inner content here -->
</DataTemplate>
...
<ControlTemplate TargetType="{x:Type Thumb}">
<ContentControl Content="{Binding}" ContentTemplate="{StaticResource InnerContent}" />
</ControlTemplate>
...
<ControlTemplate TargetType="{x:Type Button}">
<ContentControl Content="{Binding}" ContentTemplate="{StaticResource InnerContent}" />
</ControlTemplate>
我现在无法检查,但如果不起作用,则应设置具有相同属性的ContentPresenter
。
答案 2 :(得分:0)
您可以创建基本样式
<Style x:Key="BaseStyle" TargetType="Control">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Control">
...
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
并使用BasedOn
<Style x:Key="ButtonStyle" TargetType="Button" BasedOn="{StaticResource BaseStyle}">
...
</Style>