Рассмотрим этот класс BindingProxy, который является подклассом Freezable (поэтому он участвует в поисках иерархии ресурсов при добавлении в коллекцию FrameworkElement
s 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
и, таким образом, автоматически отслеживает изменения ресурса, определенного этим ключом, как и ожидалось.
Теперь, если вы хотите установить DynamicResource
в коде позади XAML, если целевой объект - FrameworkElement
, вы просто вызовете SetResourceReference
для него, вот так ...
myTextBlock.SetResourceReference(TextBlock.TextProperty, "MyTextResource")
Однако SetResourceReference
доступен только для FrameworkElement
объектов, но не Freezable
s, поэтому вы не можете использовать его для BindingProxy
.
Копаясь в исходном коде для FrameworkElement.SetResourceReference
, вы найдете это ...
public void SetResourceReference(DependencyProperty dp, object name){
base.SetValue(dp, new ResourceReferenceExpression(name));
HasResourceReference = true;
}
К сожалению, ResourceReferenceExpression
- «мясо» того, как это работает, - внутреннее, поэтому я тоже не могу добраться до этого.
Так что в коде позади, как я могу установить DynamicResource
на моем Freezable
объекте для отражения того, что я могу сделать в XAML?