对两个ControlTemplates

时间:2015-06-19 09:22:19

标签: .net wpf

我有一些视觉元素的定义,我想用于两个不同的控件(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}" />
                                   ...

3 个答案:

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

ThumbButton都来自Control的基类(不是立即,而是它的祖先之一)。因此,如果为其定义ControlTemplate,则可以为两个控件提供相同的模板。然后,按照风格,你将根据自己的需要量身定制自己的行为。

使用示例:

<Thumb Style="{StaticResource HorizontalSliderThumbStyle}" BorderBrush="AliceBlue"/>
<Button Style="{StaticResource KeyboardButtonStyle}" BorderBrush="Aquamarine"/>

enter image description here

修改

在评论中,您提到要在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

enter image description here

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