自定义控件中 Style 类型的 DependencyProperty
DependencyProperty of type Style in custom control
在自定义控件中,我想在我的模板中为 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>
我收到编译器错误 'HeadingStyle' 成员无效,因为它没有合格的类型名称。
我是否必须将 DP 的数据类型从样式修改为更具体的样式?或者是什么导致了这个错误。 DP的初始值设置为Style for TargetType TextBlock...
首先,Style
不派生自DependencyObject
,因此您不能对其设置任何绑定。
如果您希望 TextBlock
(模板的一部分)由 属性 设置样式,只需在其 Style
上设置 TemplateBinding
属性 直接(无论如何,您定义为资源的样式的目的是什么?)。这可以通过两种方式完成。一种是使用完全限定的 属性 名称:
<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
。
在自定义控件中,我想在我的模板中为 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>
我收到编译器错误 'HeadingStyle' 成员无效,因为它没有合格的类型名称。
我是否必须将 DP 的数据类型从样式修改为更具体的样式?或者是什么导致了这个错误。 DP的初始值设置为Style for TargetType TextBlock...
首先,Style
不派生自DependencyObject
,因此您不能对其设置任何绑定。
如果您希望 TextBlock
(模板的一部分)由 属性 设置样式,只需在其 Style
上设置 TemplateBinding
属性 直接(无论如何,您定义为资源的样式的目的是什么?)。这可以通过两种方式完成。一种是使用完全限定的 属性 名称:
<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
。