Wpf 如何继承控件模板

Wpf 如何继承控件模板,wpf,wpf-controls,controltemplate,Wpf,Wpf Controls,Controltemplate,我在一个WPF项目中工作,在该项目中,我过度使用了一些特殊操作的复选框控件。这是正确的 我的问题是,从主题(codeplex中的shinyred.xaml)应用的ControlTemplate,没有应用到我过度使用的控件。是否有方法继承复选框控件模板以供我的新控件使用 我能找到的所有示例都集中在继承复选框的样式上,但是没有关于ControlTemplate否,正如您所说,可以使用BasedOn属性“继承”样式,但不可能直接“继承”模板。这是可以理解的,模板继承的语义是什么?派生模板如何能够以某种

我在一个WPF项目中工作,在该项目中,我过度使用了一些特殊操作的
复选框
控件。这是正确的

我的问题是,从主题(codeplex中的shinyred.xaml)应用的
ControlTemplate
,没有应用到我过度使用的控件。是否有方法继承
复选框
控件模板
以供我的新控件使用


我能找到的所有示例都集中在继承
复选框的样式上,但是没有关于
ControlTemplate

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


对于样式,这是完全可能的,因为您可以简单地添加
设置器
触发器
,等等。模板继承唯一可能的事情是向基础模板添加
触发器
。但是,在这种情况下,您必须熟悉基本模板中的元素名称,并且基本模板中的元素名称更改可能会破坏您的派生模板。更不用说可读性问题了,您在派生模板中引用了一个名称,该名称完全是在其他地方定义的

迟来的添加说了所有这些,您的特定问题是有可能解决的(尽管我现在怀疑它仍然是您的,甚至是一个问题)。您只需使用
模板
属性的setter为控件定义样式,因此:

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

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

假设您有一个
按钮
,该按钮定义了一个您想要编辑的模板,将您的
自定义按钮
定义为如下自定义控件:

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中垂直组织复选框和标签

“但是,在这种情况下,您必须熟悉基础模板中的元素名称,基础模板中的元素名称更改可能会破坏您的派生模板。更不用说可读性问题了,您在派生模板中引用了一个名称,该名称完全是在其他地方定义的。继承通常不是这样吗?对于类型来说是这样,但这更像是从函数实现中继承,而不是从类型定义中继承。@Jeff是这样,但只适用于基类的公共和受保护元素。但似乎恰当的类比是ControlTemplate的内容是“私有的”,恐怕不是。如果您想将控件定义为UserControl(我指的是代码隐藏),而不是CustomControl,那么在任何情况下,您都必须从模板所基于的按钮或控件继承。否则,当应用ButtonBaseStyle时,您将出现编译错误。但我会让你知道,我会试试的。不幸的是,如果有办法的话,那就太好了。如果有什么需要的话,UserControl应该被视为我们所有人在代码背后继承的基础。这是我见过的最好的解决方案之一。保持默认的按钮样式和行为是可行的。不需要处理动画、触发器和状态。