我正在制作一个自定义按钮,通常会显示略微褪色的文字,并在MouseOver
或MouseDown
上显示完整力量的文字。我在我的控件的Generic.xaml
中定义了两个资源来表示这些文本颜色的画笔:
<!-- Text Brushes -->
<SolidColorBrush x:Key="NormalTextBrush" Color="Black" />
<SolidColorBrush x:Key="FadedTextBrush" Color="Gray" />
控件在该配置中编译并正常工作。
但我想让控件用户使用自定义控件的Foreground
属性设置文本颜色。所以,我将资源声明更改为:
<!-- Text Brushes -->
<SolidColorBrush x:Key="NormalTextBrush" Color="{Binding Path=Foreground, RelativeSource={RelativeSource TemplatedParent}}" />
<SolidColorBrush x:Key="FadedTextBrush" Color="{Binding Path=Foreground, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource ColorConverter}, ConverterParameter='1.2'}" />
第二个声明使用HSL
值转换器淡化文本颜色。
现在控件不起作用,我在输出窗口中收到以下错误:
System.Windows.Data Error: 2 : Cannot find governing FrameworkElement or FrameworkContentElement for target element. BindingExpression:Path=Foreground; DataItem='TaskButton' (Name='Button1'); target element is 'SolidColorBrush' (HashCode=38118303); target property is 'Color' (type 'Color')
System.Windows.Data Error: 2 : Cannot find governing FrameworkElement or FrameworkContentElement for target element. BindingExpression:Path=Foreground; DataItem=null; target element is 'SolidColorBrush' (HashCode=47449297); target property is 'Color' (type 'Color')
我不确定Data Error
告诉我的是什么。任何人都可以告诉我发生了什么以及如何解决它?谢谢你的帮助。
答案 0 :(得分:4)
RelativeSource TemplatedParent
(IIRC)在控件模板中具有意义,它指的是应用模板的控件实例上的属性。
UserControl
的内容不是UserControl
的模板。因此,此绑定不会将父UserControl
视为可行的目标。
错误消息指的是SolidColorBrush
没有模板的事实;它不会扩展System.Windows.Controls.Control
,这是(大多数)所有模板化UI控件的基本类型。有关模板的详细信息,请参阅Control.Template
。
您要做的是设置FindAncestor
的相对来源。
{Binding Foreground, RelativeSource={RelativeSource FindAncestor, AncestorType=UserControl}}
这会走向可视(或是逻辑?)树,找到类型为UserControl
的第一个祖先,然后绑定一个名为Foreground
的公共属性。
然而如果将SolidColorBrush
定义为Resource
,则无效。资源不是视觉(或逻辑树,或两者兼有?仍然不清楚)的一部分,因此RelativeSource
绑定将无法走树的祖先。
您必须直接在任何控件上使用绑定,以获得与UserControl
相同的前景色。
答案 1 :(得分:2)
问题是您不能对资源中定义的元素使用RelativeSource
绑定,因为它们不是可视树或逻辑树的一部分。
要解决此问题,您只需在设置对资源的引用的位置(在按钮的控件模板中)设置这些绑定。像这样:
<ControlTemplate TargetType="{x:Type Button}">
<Border x:Name="brd"
TextBlock.Foreground="{Binding Path=Foreground, RelativeSource={RelativeSource TemplatedParent}}">
...
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver"
Value="True">
<Setter TargetName="brd"
Property="TextBlock.Foreground"
Value="{Binding Path=Foreground, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource ColorConverter}, ConverterParameter='1.2'}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
换句话说,您无需定义资源 - NormalTextBrush
和FadedTextBrush
。