如何继承控件模板

问题描述 投票:18回答:2

我在一个WPF项目中工作,在这个项目中,我覆盖了 CheckBox 控制一些特殊行动。 这工作是正确的。

我的问题是 ControlTemplate (codeplex的shinyred.xaml),却没有应用到我的被覆盖的控件上。 有什么方法可以继承 CheckBox ControlTemplate 用于我的新控件?

我所能找到的所有示例都集中在继承我的新控件的样式上。CheckBox但没有任何关于 ControlTemplate.

wpf wpf-controls controltemplate
2个回答
21
投票

不,就像你说的那样,它可以通过使用 BasedOn 属性,但不可能直接 "继承 "一个模板。这虽然可以理解,但模板继承的语义会是什么?派生模板如何能够以某种方式添加或改变基础模板中的元素?

对于样式来说,这是完全可能的,因为你可以简单地添加 Setters, Triggers等。唯一可以想象的是,在模板继承中加入了 Triggers 到基础模板上。然而,在这种情况下,你必须对基础模板中的元素名称有深入的了解,基础模板中元素名称的改变可能会破坏你的派生模板。更不用说可读性的问题了,在你的派生模板中引用一个名字,而这个名字完全是在其他地方定义的。

迟来的补充 说了这么多,还是有可能解决你的特殊问题的(虽然我怀疑到现在还是你的问题,甚至是一个问题)。您只需为您的控件定义一个样式,并为其设置一个 Template 属性。

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

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。

© www.soinside.com 2019 - 2024. All rights reserved.