BindableBase与INotifyChanged的区别

14

有人知道BindableBase现在是否仍然可用,或者我们应该坚持使用INotifyChanged事件吗?看起来BindableBase很快就失去了它的光泽。感谢您能提供的任何信息。


1
首先,BindableBase是Prism的东西,因此与原始的WPF无关(尽管该概念可能相关)。您能否更具体地说明您的问题? - BradleyDotNET
我在我的Prism项目中使用BindableBase。它仍然非常光滑 :) - dub stylee
3个回答

30

INotifyPropertyChanged

ViewModel应实现INotifyPropertyChanged接口,并在属性更改时引发它。

public class MyViewModel : INotifyPropertyChanged
{
    private string _firstName;


    public event PropertyChangedEventHandler PropertyChanged;

    public string FirstName
    {
        get { return _firstName; }
        set
        {
            if (_firstName == value)
                return;

            _firstName = value;
            PropertyChanged(this, new PropertyChangedEventArgs("FirstName"));
        }
    }


    }
}

问题出在ICommand接口上,因为大部分代码都是重复的,并且由于它传递字符串,所以容易出错。
BindableBase是一个抽象类,实现了INotifyPropertyChanged接口并提供了SetProperty<T>。你可以将set方法减少到只有一行,ref参数允许你更新其值。下面的BindableBase代码来自INotifyPropertyChanged, The .NET 4.5 Way - Revisited
   public class MyViewModel : BindableBase
{
    private string _firstName;
    private string _lastName;

    public string FirstName
    {
        get { return _firstName; }
        set { SetProperty(ref _firstName, value); }
    }


}

     //Inside Bindable Base
    public abstract class BindableBase : INotifyPropertyChanged
    {

       public event PropertyChangedEventHandler PropertyChanged;

       protected bool SetProperty<T>(ref T storage, T value, [CallerMemberName] String propertyName = null)
       {
          if (Equals(storage, value))
          {
             return false;
          }

          storage = value;
          this.OnPropertyChanged(propertyName);
          return true;
       }

    protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
      PropertyChangedEventHandler eventHandler = this.PropertyChanged;
      if (eventHandler != null)
      {
          eventHandler(this, new PropertyChangedEventArgs(propertyName));
      }
    }
}

7

这不是两者之间的选择。

BindableBase实现了INotifyPropertyChanged接口。

因此,如果您使用BindableBase,则将使用INotifyPropertyChanged。

在使用数据绑定实现MVVM时,几乎必须使用INotifyPropertyChanged。

使用BindableBase还是其他实现取决于个人喜好和对Prism的使用情况。


BindableBase是专门为Prism设计的吗?如果我想要使用Prism和标准MVVM,我应该坚持使用INotifyPropertyChanged方法。 - ChiliYago
1
@ChiliYago,对此的任何回答都是纯粹的个人意见;决定权在于你。MVVM没有标准,它只是一组帮助你为类分配职责的指南。你使用哪种实现方式不在该模式中。 - Emond
这不是在这两者之间做出选择。那是一个误导性的陈述。这不是双向依赖关系。你可以选择只实现INotifyPropertyChanged而不使用BindableBase。这是一个关于是否想要BindableBase实现的选择。说没有选择忽略了这种区别。 - AaronLS

3

在Rohit的回答基础上,如果你使用的是.NET 4.6,你可以利用Null-conditional运算符简化OnPropertyChanged方法的实现:

protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
    this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}

INotifyPropertyChanged, The .NET 4.6 Way 更详细地解释了它。


这意味着BindableBase与普通的INotifyChanged相比几乎没有优势。此外,如果您已经有一个基类,就不能使用BindableBase。 - Slion
此外,如果您已经有一个基类,则无法使用BindableBase。但是,您的基类可以继承BindableBase。BindableBase所做的就是实现INPC。那么问题就变成了:我想使用别人的INPC实现,还是写自己的?如果您的基类已经实现了INPC,那么您选择编写自己的实现。唯一的优点是其他人已经为您完成了(减少了模板代码)。您期望获得什么优势 - highboi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接