Кто-нибудь знает, может ли BindableBase оставаться жизнеспособным или мы должны придерживаться событий INotifyChanged? Кажется, что BindableBase быстро потерял свой блеск. Спасибо за любую информацию, которую вы можете предоставить.
BindableBase vs INotifyChanged
Ответ 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;
}
}