Let’s start simple – SimpleViewModelBase
To implement the MVVM (Model-View-ViewModel) pattern, you need ViewModels that implement the INotifyPropertyChanged Interface.
I normally handle this by having a base class for all ViewModels to inherit.
public abstract class SimpleViewModelBase : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; public void OnPropertyChanged([CallerMemberName] string propertyName = "") { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } public bool setBackingField<T>(ref T storage, T value, [CallerMemberName] string propertyName = "") { var oldValue = storage; if(object.Equals(storage, value)) { return false; } storage = value; OnPropertyChanged(propertyName); return true; } }
OnPropertyChanged() will either allow for a property to announce that it has changed
public string MyProperty { get { return _myProperty; } set { _myProperty = value; OnPropertyChanged(); } }
..or that another property has changed, by passing the name of that property.
public string LastName { set { ... OnPropertyChanged(nameof(FullName)); } }
setBackingField<T>() is a helper method to allow property setters to perform all of the aspect necessary for setting their backing field and calling OnPropertyChanged to reflect that change.
public string MyProperty { get { return _myProperty; } set { setBackingField(ref _myProperty, value); } }
setBackingField<T>() will return a boolean informing if there was change.
ViewModels will inherit this and take advantage of the helper methods
public class PersonViewModel : SimpleViewModelBase { private string _firstName; public string FirstName { get => _firstName; set { if (setBackingField(ref _firstName, value)) { //Also inform Fullname OnPropertyChanged(nameof(FullName)); } } } private string _lastName; public string LastName { get => _lastName; set { if (setBackingField(ref _lastName, value)) { //Also inform Fullname OnPropertyChanged(nameof(FullName)); } } } public string FullName { get => $"{FirstName} {LastName}"; } }