行为如何访问关联元素的资源层次结构

本文关键字:元素 关联 资源 层次结构 访问 何访问 | 更新日期: 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