public void OnPropertyChanged(object newValue, [CallerMemberName] string propertyName = null) { if (propertyName == null) { throw new ArgumentNullException(nameof(propertyName)); } PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); if (!IsTracking) { return; } object oldValue; if (_firstValues.TryGetValue(propertyName, out oldValue)) { var oldCount = _dirtyValues.Count; if (Equals(newValue, oldValue)) { // remove dirty if (_dirtyValues.Remove(propertyName)) { RemovedDirty?.Invoke(propertyName); } } else { // add dirty if (!_dirtyValues.ContainsKey(propertyName)) { _dirtyValues.Add(propertyName, newValue); AddedDirty?.Invoke(propertyName); } else { _dirtyValues[propertyName] = newValue; } } var newCount = _dirtyValues.Count; if (oldCount != newCount) { DirtyCountChanged?.Invoke(); } } else { // first initialisation _firstValues.Add(propertyName, newValue); } }
public void ClearDirties() { var hadDirty = _dirtyValues.Count != 0; foreach (var pair in _dirtyValues) { _firstValues[pair.Key] = pair.Value; } _dirtyValues.Clear(); if (hadDirty) { DirtyCountChanged?.Invoke(); } }