c#WPF XAML对ComboBox.Resources项的RelativeSource引用

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了c#WPF XAML对ComboBox.Resources项的RelativeSource引用相关的知识,希望对你有一定的参考价值。

我正在为WPF ComboBox开发一个可重用的模板。我可以通过在模板中使用这些引用来动态更改字体颜色,背景和边框:

Foreground="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=ComboBox}, Path=Foreground}"
BorderBrush="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=ComboBox}, Path=BorderBrush}"
Background="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=ComboBox}, Path=Background}"

这些很容易,因为我有可以参考的属性。

<ComboBox Margin="90,62,0,0" Height="26" Width="302"
          HorizontalAlignment="Left" VerticalAlignment="Top" 
          Focusable="False" IsReadOnly="True" MaxDropDownHeight="202" 
          Foreground="White" Background="SteelBlue" BorderBrush="White"
          Style="{StaticResource ComboBoxFlatStyle}"
          ItemContainerStyle="{StaticResource ComboBoxItemFlatStyle}">

我想做的是以类似的方式参考以下内容:

<ComboBox.Resources>
    <SolidColorBrush x:Key="ComboBoxHighlightBrush" Color="RoyalBlue" />
</ComboBox.Resources>

是否可以引用控件内的资源?我真的希望能够使用不同颜色在另一个ComboBox上重复使用此模板。

答案

我相当肯定答案是否定的,但是再次将ControlTemplates绑定到运行时目标类型的属性对吗?所以我想只要“Resources”是ComboBox对象在运行时的可访问属性就应该有办法。我通过使用snoop验证“资源”在运行时确实是一个可读属性:

enter image description here

由于Resources只是一个字典,因此我尝试将组合框下拉列表的背景设置为与您通过将这些属性添加到默认ComboBox控件模板中的“DropdownBorder”元素完全相同的方式定义:

Background="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Resources[ComboBoxHighlightBrush]}"

这可能会给你一个编译时错误,说“资源”是不可访问的 - 但这并不是一个错误,它会真正阻​​止你构建解决方案并运行它。在运行时你会发现它确实有效!

尽管它有效,但我不确定这是使模板可重用的最佳方法。除了烦人的编译时错误之外,模板的使用者必须知道这个魔术字符串才能将正确键入的画笔添加到资源字典中。

我会考虑以下几点:

  1. 轻微添加到现有UI控件的行为的常用方法是使用附加属性。您可以绑定到ControlTemplates中的附加属性。通过这种方式,您可以键入内容并且不依赖于魔术字符串。
  2. 自定义控件创建完整。在我的UI项目中,我经常需要在我的组合框下拉列表中放置默认文本或停靠项,因此我创建了一个自定义控件,它具有允许这些功能的附加依赖项属性,但也允许我修改颜色WPF的ComboBox不会让我开箱即用。

编辑根据您的代码,我认为我使用ControlTemplates对您的问题的解释是正确的..如果不是,上面的内容将没有意义。如果是这样,我也想提一下你应该做的绑定

Foreground="{TemplateBinding Foreground}"

代替

Foreground="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=ComboBox}, Path=Foreground}"

如果有什么只是为了更容易阅读它也是一个更快的绑定iirc。

以上是关于c#WPF XAML对ComboBox.Resources项的RelativeSource引用的主要内容,如果未能解决你的问题,请参考以下文章

C#/XAML/WPF 绑定部分工作,仅显示列表中的第一项

C#WinForm项目怎么转变成WPF项目?

WPF中关于对前台Xaml中Triggers的一些重要思考。

窗口消息框中的 C# WPF XAML

WPF在XAML中Binding使用StringFormat属性

WPF和Silverlight的关系