在今晚解决一个围绕动态资源的问题时,我最终得到了一个依赖于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>
该行为确实获得了资源的价值,并将动态跟踪它。但是怎么做?
行为不是 FrameworkElement,因此您不能对其调用 SetResourceReference,它也不是可视树的一部分,因此即使您可以调用 SetResourceReference,它仍然无法找到 FrameworkElement 本地的资源。然而,这正是 Behavior 所做的。如何?
换句话说,如果我们想编写我们自己的类来展示同样的行为(不是双关语),如何将自己插入到可视化树的资源层次结构中?