BindableBase vs INotifyChanged

Кто-нибудь знает, может ли BindableBase оставаться жизнеспособным или мы должны придерживаться событий INotifyChanged? Кажется, что BindableBase быстро потерял свой блеск. Спасибо за любую информацию, которую вы можете предоставить.

Ответ 1

INotifyPropertyChanged

ViewModel должен реализовывать интерфейс INotifyPropertyChanged и должен поднимать его всякий раз, когда propertychanges

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, путь .NET 4.5 - 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));
      }
    }
}

Ответ 2

Это не выбор между этими двумя.

BindableBase реализует INotifyPropertyChanged.

Итак, если вы используете BindableBase, вы будете использовать INotifyPropertyChanged.

INotifyPropertyChanged более или менее обязателен при реализации MVVM с использованием DataBinding.

Использовать BindableBase или другую реализацию зависит от предпочтения и использования Prism.

Ответ 3

Чтобы расширить ответ Rohit, если вы используете .NET 4.6, вы можете использовать оператор Null-условный и упростить метод OnPropertyChanged следующим образом:

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

INotifyPropertyChanged, путь .NET 4.6 объясняет это более подробно.

Ответ 4

BindableBase

public class BindableBase : INotifyPropertyChanged
{
    private bool _isBusy = false;
    public virtual bool IsBusy
    {
        get { return this._isBusy; }
        set
        {
            this._isBusy = value;
            this.OnPropertyChanged("IsBusy");
            this.OnPropertyChanged("Visibility");
        }
    }
    public Visibility Visibility
    {
        get
        {
            if (this.IsBusy)
                return Visibility.Visible;
            return Visibility.Collapsed;
        }
    }
    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        var eventHandler = this.PropertyChanged;
        if (eventHandler != null)
        {
            eventHandler(this, new PropertyChangedEventArgs(propertyName));
        }
    }
    public bool SetProperty<T>(ref T storage, T value, [CallerMemberName] string propertyName = null)
    {
        if (object.Equals(storage, value)) return false;
        this.OnPropertyChanged(propertyName);
        return true;

    }
}