The
PropertyChangedEventArgs Class[
^] does not provide any way to pass the previous and current values of the property.
If you want to access those values in an event handler, then you would need to create your own event args class - for example:
public class PropertyValueChangedEventArgs : PropertyChangedEventArgs
{
public PropertyValueChangedEventArgs(string? propertyName, object? previousValue, object? newValue) : base(propertyName)
{
PreviousValue = previousValue;
NewValue = newValue;
}
public object? PreviousValue { get; }
public object? NewValue { get; }
}
You would then either pass an instance of this class to the
PropertyChanged
event, and let the caller cast the event args to this class:
private void Person_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e is PropertyValueChangedEventArgs a)
{
Console.WriteLine($"{a.PropertyName} changed from {a.PreviousValue} to {a.NewValue}");
}
else
{
Console.WriteLine($"{a.PropertyName} changed.");
}
}
Or you could create a separate
PropertyValueChanged
event to make the event args type explicit:
public delegate void PropertyValueChangedEvent(object sender, PropertyValueChangedEventArgs e);
public class Person : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public event PropertyValueChangedEventHandler PropertyValueChanged;
private void SetProperty<T>(ref T field, T newValue, [CallerMemberName] string propertyName = default)
{
if (EqualityComparer<T>.Default.Equals(field, newValue)) return;
T oldValue = field;
field = newValue;
PropertyValueChangedEventArgs e = new(propertyName, oldValue, newValue);
PropertyChanged?.Invoke(this, e);
PropertyValueChanged?.Invoke(this, e);
}
private string name;
public string Name
{
get { return name; }
set { SetProperty(ref name, value); }
}
}
private void Person_PropertyValueChanged(object sender, PropertyValueChangedEventArgs e)
{
Console.WriteLine($"{e.PropertyName} changed from {e.PreviousValue} to {e.NewValue}");
}