强制重新评估依赖属性以强制值
Posted
技术标签:
【中文标题】强制重新评估依赖属性以强制值【英文标题】:Force reevaluation of dependency property to coerce value 【发布时间】:2020-10-14 22:36:32 【问题描述】:我看到这个blog post 有这个代码:
Person p = new Person("Methuselah");
p.Age = 28;
p.SuperOld = true; // Age coerced to 999
p.Age = 56; // Age still 999
p.SuperOld = false; // Age now becomes 56
我有一个非常相似的情况:当我更改一个属性(在此示例中为 SuperOld
)时,另一个属性(Age
)的值应该被强制转换为另一个值(999
)。当我重置第一个属性 (SuperOld
) 时,第二个应该获得同时设置的 baseValue (56
)。
但我不知道当第一个属性改变时我应该如何强制第二个属性。
任何提示将不胜感激。
【问题讨论】:
【参考方案1】:我会创建一个支持字段并让属性 getter 评估另一个属性:
private int _age;
public int Age
get => SuperOld ? 999 : _age;
set => _age = value;
public bool SuperOld get; set;
【讨论】:
现在图像它必须是一个依赖属性。例如用于绑定目的【参考方案2】:好吧,如果您想在SuperOld
更改时强制Age
属性,请调用CoerceValue
。您可以在microsoft docs 上阅读更多相关信息。关键信息是,此方法使用“baseValue”调用您的 CoerceValueCallback,在您的情况下为 56
。
这是一个最小的工作示例:
public class Person : DependencyObject
public static readonly DependencyProperty AgeProperty = DependencyProperty.Register(
"Age",
typeof(int),
typeof(Person),
new PropertyMetadata(default(int), AgeChanged, CoerceAge));
public static readonly DependencyProperty IsSuperOldProperty = DependencyProperty.Register(
"IsSuperOld",
typeof(bool),
typeof(Person),
new PropertyMetadata(default(bool), IsSuperOldChanged));
public int Age
get => (int)GetValue(AgeProperty);
set => SetValue(AgeProperty, value);
public bool IsSuperOld
get => (bool)GetValue(IsSuperOldProperty);
set => SetValue(IsSuperOldProperty, value);
private static void AgeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
private static object CoerceAge(DependencyObject d, object basevalue)
var person = (Person)d;
if (person.IsSuperOld)
return 999;
return basevalue;
private static void IsSuperOldChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
d.CoerceValue(AgeProperty);
这是 NUnit 测试:
[Test]
public void Should_work_like_in_blog()
Person p = new Person();
p.Age = 28;
p.IsSuperOld = true; // Age coerced to 999
Assert.That(p.Age, Is.EqualTo(999));
p.Age = 56; // Age still 999
p.IsSuperOld = false; // Age now becomes 56
Assert.That(p.Age, Is.EqualTo(56));
【讨论】:
以上是关于强制重新评估依赖属性以强制值的主要内容,如果未能解决你的问题,请参考以下文章
设计模式 - 如何仅在某些情况下强制执行对象属性(构建器模式,依赖注入)