Beispiel #1
0
        /// <summary>
        /// Adds an operation to the undo buffer.
        /// </summary>
        /// <param name="operation">The operation.</param>
        /// <remarks>
        /// <para>
        /// This methods needs to be called for every <see cref="IUndoableOperation"/> before or after
        /// it is executed by calling its <see cref="IUndoableOperation.Do"/> method. Note:
        /// <see cref="Add"/> does not execute the <see cref="IUndoableOperation"/> it will only record
        /// the operation.
        /// </para>
        /// <para>
        /// After the operation is recorded in the undo buffer it can be undone and redone by calling
        /// <see cref="Undo"/> and <see cref="Redo"/>.
        /// </para>
        /// <para>
        /// The recording of operations in the undo buffer can be temporarily disabled by setting
        /// <see cref="AcceptChanges"/> to <see langword="false"/>.
        /// </para>
        /// </remarks>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="operation"/> is <see langword="null"/>.
        /// </exception>
        /// <seealso cref="AcceptChanges"/>
        public void Add(IUndoableOperation operation)
        {
            if (operation == null)
            {
                throw new ArgumentNullException("operation");
            }

            if (AcceptChanges)
            {
                InternalUndoStack.EnqueueHead(operation);

                if (IsUndoGroupOpen)
                {
                    _numberOfOperationsInGroup++;
                }

                if (InternalUndoStack.Count == 1)
                {
                    OnPropertyChanged(new PropertyChangedEventArgs("CanUndo"));
                }

                ClearRedoStack();

                if (!IsUndoGroupOpen)
                {
                    EnforceSizeLimit();
                }
            }
        }
Beispiel #2
0
 private void ClearUndoStack()
 {
     if (InternalUndoStack.Count > 0)
     {
         InternalUndoStack.Clear();
         OnPropertyChanged(new PropertyChangedEventArgs("CanUndo"));
     }
 }
Beispiel #3
0
        void EnforceSizeLimit()
        {
            AssertNoUndoGroupOpen();
            while (InternalUndoStack.Count > _sizeLimit)
            {
                InternalUndoStack.DequeueTail();
            }

            while (InternalRedoStack.Count > _sizeLimit)
            {
                InternalRedoStack.DequeueTail();
            }
        }
Beispiel #4
0
        /// <summary>
        /// Redoes the last undone operation.
        /// </summary>
        public void Redo()
        {
            AssertNoUndoGroupOpen();
            if (InternalRedoStack.Count > 0)
            {
                IUndoableOperation operation = InternalRedoStack.DequeueHead();
                InternalUndoStack.EnqueueHead(operation);
                operation.Do();
                OnOperationRedone();

                if (InternalRedoStack.Count == 0)
                {
                    OnPropertyChanged(new PropertyChangedEventArgs("CanRedo"));
                }

                if (InternalUndoStack.Count == 1)
                {
                    OnPropertyChanged(new PropertyChangedEventArgs("CanUndo"));
                }

                EnforceSizeLimit();
            }
        }