“尝试”属性更改的事件

时间:2011-10-17 13:43:12

标签: .net design-patterns properties event-log

(使用.Net 3.5)我有一个从外部数据源导入设置的例程,之后我需要向用户显示伪日志,详细说明哪些属性已更新。通常我会通过property_changed事件跟踪属性更新。但是,当数据源中的值恰好已经等于属性值时,即使调用了属性集,也不会引发property_changed事件。但我仍然需要向用户显示这些属性,因为它们是从数据源“更新”的。

这里的常见模式是什么?我的属性setter-“property_attemptedset”中是否还需要另一个事件(另外还有property_changed)?

编辑:所以有一个建议是我不会在属性设置器中进行相等检查,因此无论如何都会触发“property_changed”。但我总是被告知过滤实际的价值变化。这不是最佳做法吗?

3 个答案:

答案 0 :(得分:2)

嗯,当你实际上没有改变属性的值时,避免引发 PropertyChanged 事件是很常见的......但是没有规则说明你必须这样做。只需删除setter中的任何逻辑,该逻辑将根据当前值检查新值。

答案 1 :(得分:1)

如果你写这样的属性:

public string LastName{
    get { return lastName; }
    set {
        lastName = value;
        RaisePropertyChanged("LastName");
    }
}

它应始终触发PropertyChanged - 事件,即使值相同。您无需为此启动任何其他事件。

编辑

除了您的编辑:是的,检查实际值更改是最佳做法,但如果您的方案需要跟踪非值更改,我不明白为什么您无法更改它。 “最佳实践”并不意味着“打破这个规则和进入监狱”的事情吧? 但是如果这些类有任何其他观察者,它们也依赖于常见的PropertyChanged行为,你总是可以扩展属性并抛出另一个(自定义)事件,就像你提到的那样:

    public event PropertyChangedEventHandler AttemptedPropertyChanged;
    public void RaiseAttemptedPropertyChanged(string propName)
    {
        if (AttemptedPropertyChanged != null)
        {
            AttemptedPropertyChanged(this, new PropertyChangedEventArgs(propName));
        }
    }


    public string LastName{
        get { return lastName; }
        set {                
            RaiseAttemptedPropertyChanged("LastName");
            if (lastName == value) return;
            lastName = value;
            RaisePropertyChanged("LastName");
        }
    }

答案 2 :(得分:1)

听起来你基于你所写的内容的下一步有时会阻止这种变化。如果是这样,我会引入一个像BeforePropertySet这样的新事件,并传递一个允许取消的事件对象。

这与最佳实践保持一致(防止有人某天出现使用property以传统方式改变的可能性,并且无法弄清楚为什么他们的代码不起作用),澄清你正在做什么,并让你分开关注点好一点。