English 中文(简体)
将资源绑定到自定义控件属性
原标题:Binding a resource to a custom control property

我正在创建一个自定义按钮,该按钮正常显示略微褪色的文本,并在MouseOverMouseDown上显示全强度文本。我在控件的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 )

我不确定数据错误告诉了我什么。有人能告诉我发生了什么以及如何修复吗?谢谢你的帮助。

最佳回答

RelativeSource TemplatedPParentonly(IIRC)在控件模板中具有含义,它指的是应用该模板的控件实例上的属性。

UserControl的内容不是UserControl的模板。因此,此绑定不会将父UserControl视为可行的目标。

错误消息指的是SolidColorBrush没有模板;它不扩展System.Windows.Controls.Control,后者是(大多数)所有模板化UI控件的基本类型。请参阅Control.Template了解有关模板的详细信息。

您要做的是设置FindAncestor的相对源。

{Binding Foreground, RelativeSource={RelativeSource FindAncestor, AncestorType=UserControl}}

这将沿着可视化(或者它是逻辑的?)树向上走,以找到UserControl类型的第一个祖先,然后绑定到名为Foreground的公共属性。

但是如果SolidColorBrush被定义为资源,这将不起作用。资源不是可视化(或逻辑树,或两者都不清楚)的一部分,因此RelativeSource绑定将无法遍历树的祖先。

您必须直接对任何希望具有与UserControl相同前景色的控件使用绑定。

问题回答

问题是,不能对资源中定义的元素使用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>

换句话说,您不需要定义资源-NormalTextBrushFadedTextBrush





相关问题
WPF convert 2d mouse click into 3d space

I have several geometry meshes in my Viewport3D, these have bounds of (w:1800, h:500, d:25). When a user clicks in the middle of the mesh, I want the Point3D of (900, 500, 25)... How can I achieve ...

Editing a xaml icons or images

Is it possible to edit a xaml icons or images in the expression design or using other tools? Is it possible to import a xaml images (that e.g you have exported) in the expression designer for editing?...

WPF: writing smoke tests using ViewModels

I am considering to write smoke tests for our WPF application. The question that I am faced is: should we use UI automation( or some other technology that creates a UI script), or is it good enough to ...

WPF - MVVM - NHibernate Validation

Im facing a bit of an issue when trying to validate a decimal property on domain object which is bound to a textbox on the view through the viewmodel. I am using NHibernate to decorate my property on ...

How do WPF Markup Extensions raise compile errors?

Certain markup extensions raise compile errors. For example StaticExtension (x:Static) raises a compile error if the referenced class cannot be found. Anyone know the mechanism for this? Is it baked ...

WPF design-time context menu

I am trying to create a custom wpf control, I m wondering how I can add some design-time features. I ve googled and can t seem to get to my goal. So here s my simple question, how can I add an entry ...

How to combine DataTrigger and EventTrigger?

NOTE I have asked the related question (with an accepted answer): How to combine DataTrigger and Trigger? I think I need to combine an EventTrigger and a DataTrigger to achieve what I m after: when ...

热门标签