It probably wouldn't hurt to have a base class that accumulates some useful operations associated with INotifyPropertyChanged
. I usually use something akin to the following:
public class NotifiableBase : INotifyPropertyChanged
{
#region Utility methods
/// <summary>
/// Notify of a property change and optional additional dependencies.
/// </summary>
public void Notify([CallerMemberName] string propertyName = null, params string[] additionalNames)
{
OnPropertyChanged(propertyName);
foreach (var name in additionalNames)
{
OnPropertyChanged(name);
}
}
/// <summary>
/// Makes a change to the supplied reference if different.
/// If different, notify of a property change and optional additional dependencies.
/// </summary>
public bool ChangeAndNotify<T>(ref T toChange, T newValue, [CallerMemberName] string propertyName = null, params string[] additionalNames)
{
var cmp = EqualityComparer<T>.Default;
if (cmp.Equals(toChange, newValue) == false)
{
toChange = newValue;
OnPropertyChanged(propertyName);
foreach (var name in additionalNames)
{
OnPropertyChanged(name);
}
return true;
}
return false;
}
/// <summary>
/// Makes a change to the supplied reference if different.
/// If different, notify of a property change and optional additional dependencies then call action.
/// </summary>
public bool ChangeAndNotifyWithAction<T>(ref T toChange, T newValue, Action action, [CallerMemberName] string propertyName = null, params string[] additionalNames)
{
var ret = ChangeAndNotify(ref toChange, newValue, propertyName, additionalNames);
if (ret)
{
action();
}
return ret;
}
#endregion
#region INotifyPropertyChanged implementation
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
#endregion
}
The calls are styled to allow you to do most things in one line thus:
public int PropertyName
{
get { return _propertyName; }
set { ChangeAndNotify(ref _propertyName, value); }
}
or
public int PropertyName
{
get { return _propertyName; }
set { ChangeAndNotify(ref _propertyName, value, "PropertyName", "AdditionalRelatedPropertyName"); }
}
or
public int PropertyName
{
get { return _propertyName; }
set { ChangeAndNotify(ref _propertyName, value, () => SomeActionOnSuccess()); }
}