【发布时间】:2018-09-03 08:15:35
【问题描述】:
考虑这个 BindingProxy 类,它是 Freezable 的子类(因此当添加到 FrameworkElement 的 Resources 集合时,它会参与资源层次结构查找)...
public class BindingProxy : Freezable {
public BindingProxy(){}
public BindingProxy(object value)
=> Value = value;
protected override Freezable CreateInstanceCore()
=> new BindingProxy();
#region Value Property
public static readonly DependencyProperty ValueProperty = DependencyProperty.Register(
nameof(Value),
typeof(object),
typeof(BindingProxy),
new FrameworkPropertyMetadata(default));
public object Value {
get => GetValue(ValueProperty);
set => SetValue(ValueProperty, value);
}
#endregion Value Property
}
你像这样将它添加到你的 XAML...
<Window.Resources>
<is:BindingProxy x:Key="TestValueProxy" Value="{DynamicResource TestValue}" />
</Window.Resources>
如您所见,Value 设置为 DynamicResource,因此它会自动跟踪对该键定义的资源的更改,正如预期的那样。
现在,如果您想在代码隐藏而不是 XAML 中设置 DynamicResource,如果目标对象是 FrameworkElement,您只需在其上调用 SetResourceReference,就像这样...
myTextBlock.SetResourceReference(TextBlock.TextProperty, "MyTextResource")
但是,SetResourceReference 仅适用于 FrameworkElement 对象,而不是 Freezables,因此您不能在 BindingProxy 上使用它。
深入研究FrameworkElement.SetResourceReference 的源代码,你会发现这个...
public void SetResourceReference(DependencyProperty dp, object name){
base.SetValue(dp, new ResourceReferenceExpression(name));
HasResourceReference = true;
}
不幸的是,ResourceReferenceExpression——它的工作原理的“核心”——是内部的,所以我也无法理解。
那么在代码隐藏中,如何在基于Freezable 的对象上设置DynamicResource 以反映我在XAML 中可以执行的操作?
【问题讨论】:
-
为什么不在
proxy.Value = dynamicResourceExtension.ProvideValue(null);这样的代码中使用DynamicResourceExtension? -
我实际上已经尝试过了,但有趣的是,不是通过传递“null”。我正在缓存服务提供者,这是问题的一部分。让我看看'null'是否修复它。 (顺便说一句,为了完整起见,您能否将此作为代码示例供其他人遵循?只是在 SO 上看起来更好。)
标签: c# wpf dynamicresource freezable