![](/img/trans.png)
[英]How do you set the FrameworkElement.Width property to the value of a qualifiedDouble, in the code-behind?
[英]How can you set a DynamicResource in code-behind if the target is not a FrameworkElement?
考虑这个 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
对象,不适用于Freezable
因此您不能在BindingProxy
上使用它。
深入研究FrameworkElement.SetResourceReference
的源代码,你会发现这个......
public void SetResourceReference(DependencyProperty dp, object name){
base.SetValue(dp, new ResourceReferenceExpression(name));
HasResourceReference = true;
}
不幸的是, ResourceReferenceExpression
是如何工作的“肉”——是内部的,所以我也无法做到这一点。
因此,在代码隐藏中,如何在基于Freezable
的对象上设置DynamicResource
以反映我可以在 XAML 中执行的操作?
您可以在代码中使用DynamicResourceExtension
实例:
var proxy = new BindingProxy();
var dynamicResourceExtension = new DynamicResourceExtension("TestValue");
proxy.Value = dynamicResourceExtension.ProvideValue(null);
如果您在此处看到代码参考,您将看到当serviceProvider
为 null 时, ProvideValue
返回一个ResourceReferenceExpression
。 与SetResourceReference
所做的几乎相同
使用反射创建一个ResourceReferenceExpression
:
Type type = typeof(System.Windows.Window).Assembly.GetType("System.Windows.ResourceReferenceExpression");
ConstructorInfo ctor = type.GetConstructors()[0];
object resourceReferenceExpression = ctor.Invoke(new object[] { "TestValue" });
TestValueProxy.SetValue(BindingProxy.ValueProperty, resourceReferenceExpression);
显然,如果内部类型更改,此代码可能会中断,但如果您确实需要能够将DynamicResource
动态应用于Freezable
的值,则您无能为力。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.