/// <summary> /// Fires or caches the DataChanged event. /// </summary> /// <remarks> /// Sets <see cref="DataState"/> property to <see cref="DataObjectState.Changed"/> when properties change. /// </remarks> protected void DoDataChanged(DataObjectChangeAction action, Guid?propertyId) { lock (SyncRoot) { // Validate and update state when properties change if (action == DataObjectChangeAction.Property) { if (DataState == DataObjectState.Deleted) { throw new InvalidOperationException(); } DataState = DataObjectState.Changed; } // Fire or cache event if (EventsAreEnabled) { // Fire event immediately OnDataChanged(new DataObjectChangeEventArgs(action, propertyId.HasValue ? new[] { propertyId.Value } : null)); } else { // Cache event... // Add any chaned property to instance cache if (propertyId.HasValue && !_instancePropertiesChanged.Contains(propertyId.Value)) { _instancePropertiesChanged.Add(propertyId.Value); } // Process commit or clear instance property change cache depending on action switch (action) { case DataObjectChangeAction.Create: case DataObjectChangeAction.Update: // Commit all instance property changes foreach (var instancePropertyId in _instancePropertiesChanged) { if (!_committedPropertiesChanged.Contains(instancePropertyId)) { _committedPropertiesChanged.Add(instancePropertyId); } } _instancePropertiesChanged.Clear(); // Update is ignored if Create is cached if ((action == DataObjectChangeAction.Update && !_lastChangeAction.HasValue && _lastChangeAction != DataObjectChangeAction.Create) || (action == DataObjectChangeAction.Create)) { _lastChangeAction = action; } break; case DataObjectChangeAction.Read: // Clear all non-committed instance property changes on read _instancePropertiesChanged.Clear(); if (_lastChangeAction.HasValue && _lastChangeAction.Value == DataObjectChangeAction.Property) { _lastChangeAction = null; } // Read is weakest action if (!_lastChangeAction.HasValue) { _lastChangeAction = action; } break; case DataObjectChangeAction.Delete: // Clear all instance and committed property changes on delete _committedPropertiesChanged.Clear(); _instancePropertiesChanged.Clear(); // Delete is strongest action, unless preceded by Create if (!_lastChangeAction.HasValue || _lastChangeAction.Value != DataObjectChangeAction.Create) { // Delete overrides any other value _lastChangeAction = action; } else { // Delete after Create cancels out all changes _committedPropertiesChanged.Clear(); _instancePropertiesChanged.Clear(); _lastChangeAction = null; } break; case DataObjectChangeAction.Property: // Add property to instance cache if (!propertyId.HasValue) { throw new ArgumentNullException("propertyId"); } if (!_instancePropertiesChanged.Contains(propertyId.Value)) { _instancePropertiesChanged.Add(propertyId.Value); } // Instance changes only override read if (!_lastChangeAction.HasValue || _lastChangeAction.Value == DataObjectChangeAction.Read) { _lastChangeAction = action; } break; } } } }
/// <summary> /// Creates an instance with the specified values. /// </summary> public DataObjectChangeEventArgs(DataObjectChangeAction action, Guid[] keys) : base(keys) { Action = action; }