行为如何访问关联元素的资源层次结构
本文关键字:元素 关联 资源 层次结构 访问 何访问 | 更新日期: 2023-09-27 18:22:29
在今晚解决一个关于动态资源的问题时,我最终得到了一个依赖于Behavior
类参与其相关框架元素的资源层次结构的能力的解决方案。例如,考虑以下
<Application>
<Application.Resources>
<system:String x:Key="TestString">In App Resources</system:String>
</Application.Resources>
</Application>
<Window>
<Window.Resources>
<system:String x:Key="TestString">In Window Resources/system:String>
</Window.Resources>
<Border>
<Border.Resources>
<system:String x:Key="TestString">In Border Resources</system:String>
</Border.Resources>
<TextBlock Text="{DynamicResource TestString}" />
</Border>
</Window>
TextBlock将显示来自边界的资源。但是,如果我这样做。。。
public void Test()
{
var frameworkElement = new FrameworkElement();
var testString = (string)frameworkElement.FindResource("TestString");
}
它从应用程序中找到一个,因为它不是可视化树的一部分。
也就是说,如果我这样做。。。
public class MyBehavior : Behavior<FrameworkElement>
{
public string Value... // Implement this as a DependencyProperty
}
然后像这样将其添加到TextBlock。。。
<TextBlock Text="{DynamicResource TestString}">
<i:Interaction.Behaviors>
<local:MyBehavior Value="{DynamicResource TestString}" />
</i:Interaction.Behaviors>
</TextBlock>
行为确实获取资源的值,并将动态跟踪它。但是怎么做呢?
Behavior不是FrameworkElement,因此您不能对其调用SetResourceReference,也不是Visual Tree的一部分,因此即使您可以调用SetResourceReference,它仍然找不到FrameworkElement本地的资源。然而,这正是行为的作用。怎样
换言之,如果我们想编写自己的类,也表现出同样的行为(并非双关语),我们将如何将自己插入到视觉树的资源层次结构中?
好吧,我想我找到了!秘密是一个可冻结的。简单地说,当您将Freezable添加到FrameworkElement的资源中时,该Freezable上分配了DynamicResource的任何DependencyProperty都将正确解析。
利用这些知识,我创建了一个DynamicResourceBinding,使您可以像使用任何其他DynamicResource一样使用它,但还可以指定转换器、格式字符串等。
这里有一个链接到StackOverflow上的那个页面,我在这里为动态和静态资源做这件事。。。
Post33816511:如何创建DynamicResourceBinding