如何继承控制模板

时间:2010-01-09 18:56:38

标签: wpf wpf-controls controltemplate

我正在开发一个WPF项目,我已经超越了CheckBox控件以进行一些特殊操作。这是正常的。

我的问题是从主题中应用的ControlTemplate(来自codeplex的shinyred.xaml)不会应用于我的过度控制。有没有办法继承CheckBox ControlTemplate以供我的新控件使用?

我能找到的所有样本都专注于继承CheckBox的样式,但没有关于ControlTemplate的样式。

2 个答案:

答案 0 :(得分:19)

不,正如您所说,可以使用BasedOn属性“继承”样式,但不可能直接“继承”模板。这是可以理解的,模板继承的语义是什么?派生模板如何以某种方式添加或更改基本模板中的元素?

使用样式完全有可能,因为您可以简单地添加SettersTriggers等。模板继承唯一可以实现的是将Triggers添加到基本模板。但是,在这种情况下,您必须对基本模板中的元素名称有深入的了解,并且基本模板中的元素名称更改可能会破坏派生的元素名称。更不用说可读性问题,您可以在派生模板中引用一个名称,该名称在其他地方完全定义。

迟来的加法说了这么多,有可能解决你的特定问题(虽然我现在怀疑它仍然是你的,甚至是一个问题)。您只需使用Template属性的setter为您的控件定义样式:

<Style TargetType="<your type>">
    <Setter Property="Template" Value="{StaticResource <existing template resource name>}"/>
</Style>

答案 1 :(得分:2)

记住@Aviad所说的话,以下是一种解决方法:

假设您有一个Button,它定义了您要显示的模板,将CustomButton定义为“自定义控件”,如下所示:

public class CustomButton : Button
{

    static CustomButton()
    {
        DefaultStyleKeyProperty.OverrideMetadata(typeof(CustomButton), new FrameworkPropertyMetadata(typeof(CustomButton)));
    }


    public static readonly DependencyProperty TextProperty = DependencyProperty.Register("Text",
        typeof(string),  typeof(CustomButton), new UIPropertyMetadata(null));

    public string Text
    {
        get { return (string)GetValue(TextProperty); }
        set { SetValue(TextProperty, value); }
    }
}

然后转到您的Generic.xaml并定义以下内容:

 <Style
    x:Key="CustomButtonStyle" TargetType="{x:Type local:CustomButton}">
    <Setter Property="FontSize" Value="18" /> <!--Override the font size -->
    <Setter Property="FontWeight" Value="Bold" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type local:CustomButton}">
                <Button Style="{StaticResource ButtonStyleBase}" 
                    Height="{TemplateBinding Height}" 
                        Command="{Binding RelativeSource={RelativeSource AncestorType={x:Type local:CustomButton}}, Path=Command}"
                        CommandParameter="{Binding}"
                        Width="{TemplateBinding Width}">
                    <Grid>
                        <StackPanel>
                            <Image Source="Image/icon.jpg" />
                            <TextBlock Text="{TemplateBinding Text}"></TextBlock>
                        </StackPanel>
                    </Grid>
                </Button>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

请注意,我们要继承模板的按钮包装在我的新模板中,并且样式设置为现有按钮。与复选框相同,并例如在CustomCheckBox的新ControlTemplate内垂直组织复选框和标签。