/// <summary> /// Attempts to remove all info related to a key from the dictionary. /// </summary> /// <param name="key">The key to remove data from.</param> /// <returns><see langword="true" /> if the removal was successful, <see langword="false" /> otherwise.</returns> public bool Remove(TKey key) { // PRECONDITIONS // Current object not disposed this.RequiresNotDisposed(); // ACTION bool result; IDictionaryCollectionAdapter <TKey, TValue> container = InternalContainer; // Within a read/write lock using (ReadWriteSynchronizationLocker locker = ReadWriteLock()) { // Find out if there's anything to remove if (!container.TryGetValue( key, out TValue? value)) { return(false); } // Upgrade the locker to a write lock locker.Upgrade(); // Do the actual removal result = container.Remove(key); // Push undo level if (result) { PushUndoLevel( new DictionaryRemoveStateChange <TKey, TValue>( key, value)); } } // NOTIFICATION AND RETURN if (result) { BroadcastChange(); } return(result); }
/// <summary> /// Has the last undone operation redone. /// </summary> /// <param name="undoRedoLevel">A level of undo, with contents.</param> /// <param name="toInvokeOutsideLock">An action to invoke outside of the lock.</param> /// <param name="state">The state object to pass to the invocation.</param> /// <returns><see langword="true" /> if the redo was successful, <see langword="false" /> otherwise.</returns> protected override bool RedoInternally( StateChange undoRedoLevel, out Action <object> toInvokeOutsideLock, out object state) { if (base.RedoInternally( undoRedoLevel, out toInvokeOutsideLock, out state)) { return(true); } switch (undoRedoLevel) { case AddUndoLevel <KeyValuePair <TKey, TValue> > aul: { IDictionaryCollectionAdapter <TKey, TValue> container = this.InternalContainer; container.Add( aul.AddedItem.Key, aul.AddedItem.Value); toInvokeOutsideLock = innerState => ((ObservableDictionary <TKey, TValue>)innerState).BroadcastChange(); state = this; break; } case RemoveUndoLevel <KeyValuePair <TKey, TValue> > rul: { IDictionaryCollectionAdapter <TKey, TValue> container = this.InternalContainer; container.Remove(rul.RemovedItem.Key); toInvokeOutsideLock = innerState => ((ObservableDictionary <TKey, TValue>)innerState).BroadcastChange(); state = this; break; } case ClearUndoLevel <KeyValuePair <TKey, TValue> > _: { this.InternalContainer.Clear(); toInvokeOutsideLock = innerState => ((ObservableDictionary <TKey, TValue>)innerState).BroadcastChange(); state = this; break; } case DictionaryAddUndoLevel <TKey, TValue> daul: { IDictionaryCollectionAdapter <TKey, TValue> container = this.InternalContainer; container.Add( daul.Key, daul.Value); toInvokeOutsideLock = innerState => ((ObservableDictionary <TKey, TValue>)innerState).BroadcastChange(); state = this; break; } case DictionaryRemoveUndoLevel <TKey, TValue> raul: { IDictionaryCollectionAdapter <TKey, TValue> container = this.InternalContainer; container.Remove(raul.Key); toInvokeOutsideLock = innerState => ((ObservableDictionary <TKey, TValue>)innerState).BroadcastChange(); state = this; break; } case DictionaryChangeUndoLevel <TKey, TValue> caul: { IDictionaryCollectionAdapter <TKey, TValue> container = this.InternalContainer; container[caul.Key] = caul.NewValue; toInvokeOutsideLock = innerState => ((ObservableDictionary <TKey, TValue>)innerState).BroadcastChange(); state = this; break; } default: { toInvokeOutsideLock = null; state = null; return(false); } } return(true); }
/// <summary> /// Has the last undone operation redone. /// </summary> /// <param name="undoRedoLevel">A level of undo, with contents.</param> /// <param name="toInvokeOutsideLock">An action to invoke outside of the lock.</param> /// <param name="state">The state object to pass to the invocation.</param> /// <returns><see langword="true" /> if the redo was successful, <see langword="false" /> otherwise.</returns> protected override bool RedoInternally( StateChangeBase undoRedoLevel, out Action <object?>?toInvokeOutsideLock, out object?state) { if (base.RedoInternally( undoRedoLevel, out toInvokeOutsideLock, out state)) { return(true); } switch (undoRedoLevel) { case AddStateChange <KeyValuePair <TKey, TValue> >(var(key, value), _): { IDictionaryCollectionAdapter <TKey, TValue> container = InternalContainer; _ = container.Add( key, value); toInvokeOutsideLock = innerState => { if (innerState == null) { return; } ((ObservableDictionary <TKey, TValue>)innerState).BroadcastChange(); }; state = this; break; } case RemoveStateChange <KeyValuePair <TKey, TValue> >(_, var keyValuePair): { IDictionaryCollectionAdapter <TKey, TValue> container = InternalContainer; _ = container.Remove(keyValuePair.Key); toInvokeOutsideLock = innerState => { if (innerState == null) { return; } ((ObservableDictionary <TKey, TValue>)innerState).BroadcastChange(); }; state = this; break; } case ClearStateChange <KeyValuePair <TKey, TValue> > : { InternalContainer.Clear(); toInvokeOutsideLock = innerState => { if (innerState == null) { return; } ((ObservableDictionary <TKey, TValue>)innerState).BroadcastChange(); }; state = this; break; } case DictionaryAddStateChange <TKey, TValue>(var key, var value): { IDictionaryCollectionAdapter <TKey, TValue> container = InternalContainer; _ = container.Add( key, value); toInvokeOutsideLock = innerState => { if (innerState == null) { return; } ((ObservableDictionary <TKey, TValue>)innerState).BroadcastChange(); }; state = this; break; } case DictionaryRemoveStateChange <TKey, TValue>(var key, _): { IDictionaryCollectionAdapter <TKey, TValue> container = InternalContainer; _ = container.Remove(key); toInvokeOutsideLock = innerState => { if (innerState == null) { return; } ((ObservableDictionary <TKey, TValue>)innerState).BroadcastChange(); }; state = this; break; } case DictionaryChangeStateChange <TKey, TValue>(var key, var newValue, _): { IDictionaryCollectionAdapter <TKey, TValue> container = InternalContainer; container[key] = newValue; toInvokeOutsideLock = innerState => { if (innerState == null) { return; } ((ObservableDictionary <TKey, TValue>)innerState).BroadcastChange(); }; state = this; break; } default: { toInvokeOutsideLock = null; state = null; return(false); } } return(true); }