为什么没有人使用INotifyPropertyChanging?

mic*_*ael 13 c# wpf mvvm

我知道MVVM大量使用INotifyPropertyChanged,但我从未见过使用过任何INotifyPropertyChanging.有什么理由吗?

如果我确实想要使用它,那么将它集成到我的MVVM框架中的好方法是什么?我知道你不应该MessageBox在你的ViewModel 上使用,因为那时你无法对它进行单元测试.那么如何进行警报,然后继续使用PropertyChange(如果适用)?

use*_*116 12

需要记住的INotifyPropertyChanging是,你无法阻止变化的发生.这仅允许您记录发生的更改.

我在我的框架中使用它进行更改跟踪,但它不是停止更改的适当方法.

您可以ViewModelBase使用自定义界面/事件对扩展您的:

delegate void AcceptPendingChangeHandler(
    object sender,
    AcceptPendingChangeEventArgs e);

interface IAcceptPendingChange
{
    AcceptPendingChangeHandler PendingChange;
}

class AcceptPendingChangeEventArgs : EventArgs
{
    public string PropertyName { get; private set; }
    public object NewValue { get; private set; }
    public bool CancelPendingChange { get; set; }
    // flesh this puppy out
}

class ViewModelBase : IAcceptPendingChange, ...
{
    protected virtual bool RaiseAcceptPendingChange(
        string propertyName,
        object newValue)
    {
        var e = new AcceptPendingChangeEventArgs(propertyName, newValue)
        var handler = this.PendingChange;
        if (null != handler)
        {
            handler(this, e);
        }

        return !e.CancelPendingChange;
    }
}
Run Code Online (Sandbox Code Playgroud)

此时,您需要按惯例将其添加到视图模型中:

class SomeViewModel : ViewModelBase
{
     public string Foo
     {
         get { return this.foo; }
         set
         {
             if (this.RaiseAcceptPendingChange("Foo", value))
             {
                 this.RaiseNotifyPropertyChanging("Foo");
                 this.foo = value;
                 this.RaiseNotifyPropretyChanged("Foo");
             }
         }
     }
}
Run Code Online (Sandbox Code Playgroud)


小智 7

INotifyPropertyChanging 是与 Linq to SQL 一起使用的优化。当一个对象实现这个接口时,它使用变化事件作为信号来缓存属性的旧值。如果对象没有实现这个接口,那么它会一直缓存属性值,增加内存使用。有关更多详细信息,请参阅INotifyPropertyChanging 接口如何帮助限制内存消耗