自定义控件中Style类型的DependencyProperty

时间:2016-09-09 08:51:30

标签: c# wpf xaml styles dependency-properties

在自定义控件中,我想在我的模板中为TextBlock使用样式(作为DependencyProperty)。

MyControl.cs

public static DependencyProperty HeadingStyleProperty =
    DependencyProperty.Register("HeadingStyle",
                                typeof (Style),
                                typeof (MyControlElement),
                                new PropertyMetadata(new Style(typeof(TextBlock))));

public Style HeadingStyle {
    get { return (Style) GetValue(HeadingStyleProperty); }
    set { SetValue(HeadingStyleProperty, value); }
}

MyControl.xaml

<ResourceDictionary ...>
    <Style TargetType="local:MyControl">
        <Style.Resources>
            <!-- Getting error on BasedOn="TemplateBinding -->
            <Style TargetType="TextBlock" BasedOn="{TemplateBinding HeadingStyle}" x:Key="Heading" />
        </Style.Resources>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate>
                    <TextBlock Style="{StaticResource Heading}" Text="StyledHeading" />
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</ResourceDictionary>

我收到编译错误&#39; HeadingStyle&#39;成员无效,因为它没有合格的类型名称。

我是否必须将我的DP的DataType从Style更改为更具体的?或是什么原因导致此错误。 DP的初始值设置为TargetType TextBlock的样式...

1 个答案:

答案 0 :(得分:2)

首先,Style 派生自DependencyObject,因此您无法对其进行任何绑定。

如果您希望自己的TextBlock(模板的一部分)由您的属性设置样式,只需直接在其TemplateBinding属性上设置Style(目的是什么)您定义为资源的样式无论如何?)。这可以通过两种方式完成。一种是使用完全限定的属性名称:

<ControlTemplate>
    <TextBlock Style="{TemplateBinding local:MyControl.HeadingStyle}" (...) />
</ControlTemplate>

另一种更常用的方法是使用简化的属性名称,但它需要指定ControlTemplate.TargetType

<ControlTemplate TargetType="{x:Type local:MyControl}">
    <TextBlock Style="{TemplateBinding HeadingStyle}" (...) />
</ControlTemplate>

第二种方法有效,因为XAML解析器足够聪明,知道如何解析HeadingStyle属性 - 如果你没有指定ControlTemplate.TargetType,你就会得到完全相同的你现在得错了。

您当然可以通过使用完全限定的属性名称来欺骗编译器编译代码:

<Style x:Key="Heading" BasedOn="{TemplateBinding local:MyControl.HeadingStyle}" (...) />

但这会导致运行时错误,指出TemplateBindingExpression无法转换为Style