强制重新评估依赖项 属性 以强制值

Force reevaluation of dependency property to coerce value

我看到这个 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).

但是我不知道我应该如何在第一个更改时强制转换第二个属性。

如有任何提示,我们将不胜感激。

我会创建一个支持字段并让 属性 getter 评估另一个 属性:

{
    private int _age;
    public int Age
    {
        get => SuperOld ? 999 : _age;
        set => _age = value;
    }

    public bool SuperOld { get; set; }
}

好吧,如果你想在 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:

    [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));
    }