UndoRedoTransaction Class
Groups several actions into a single undoable/redoable unit. Create one with UndoRedoManager.CreateTransaction and commit it to record it as a single step. Committing is all-or-nothing: if one of the actions fails, the actions that already ran are reverted before the exception is propagated.
public sealed class UndoRedoTransaction : IUndoRedoAction, IAsyncDisposableRemarks
Disposal rolls the transaction back unless UndoRedoTransaction.CommitAsync was called, so leaving the scope because of an exception discards the work instead of applying it. Nested transactions must use the same TransactionExecutionMode as the transaction they are nested in, and must be completed from the innermost out.
Example
var manager = new UndoRedoManager();
var list = new List<string>();
await using (var transaction = manager.CreateTransaction())
{
await manager.RecordActionAsync(() => list.Add("first"), () => list.Remove("first"));
await manager.RecordActionAsync(() => list.Add("second"), () => list.Remove("second"));
await transaction.CommitAsync();
}
Assert.Equal(["first", "second"], list);
// A single UndoAsync reverts both actions
await manager.UndoAsync();
Assert.Empty(list);- Implements
Properties
| Name | Description |
|---|---|
| AllowToMergeWithPrevious | Gets a value indicating whether this action may be merged with the previous action in the undo buffer. |
| Description | Gets a human-readable description of the action, for display in an undo history. Defaults to null. |
| IsCompleted | Gets a value indicating whether the transaction has been committed or rolled back. |
| Mode | Gets a value indicating when the actions recorded in this transaction are executed. |
AllowToMergeWithPrevious
UndoRedoTransaction.csDescription
UndoRedoTransaction.csIsCompleted
UndoRedoTransaction.csGets a value indicating when the actions recorded in this transaction are executed.
public TransactionExecutionMode Mode { get; }Property value
Methods
| Name | Description |
|---|---|
| CommitAsync(CancellationToken) | Commits the transaction, recording it as a single undo step. |
| DisposeAsync() | Rolls the transaction back if it has not already been committed or rolled back, so leaving the scope because of an exception discards the recorded actions instead of applying them. Call UndoRedoTransaction.CommitAsync to keep them. |
| Meziantou.Framework.UndoRedo.IUndoRedoAction.ExecuteAsync(CancellationToken) | Applies the change encapsulated by this action. |
| Meziantou.Framework.UndoRedo.IUndoRedoAction.TryToMergeAsync(IUndoRedoAction, CancellationToken) | Attempts to merge a following action into this one instead of recording it as a separate step. Useful for long chains of consecutive operations of the same kind (e.g. dragging or typing). |
| Meziantou.Framework.UndoRedo.IUndoRedoAction.UnExecuteAsync(CancellationToken) | Reverts the change previously applied by IUndoRedoAction.ExecuteAsync. |
| RollbackAsync(CancellationToken) | Rolls back the transaction, reverting any actions that were already executed. |
CommitAsync(CancellationToken)
UndoRedoTransaction.csCommits the transaction, recording it as a single undo step.
public ValueTask CommitAsync(CancellationToken cancellationToken = default)Parameters
cancellationTokenCancellationToken- A token to cancel the operation.
Returns
Exceptions
InvalidOperationException- The transaction is already completed, it is not the innermost open transaction, or an action is currently executing.
AggregateException- An action failed and reverting the actions that already ran failed too, leaving them applied.
DisposeAsync()
UndoRedoTransaction.csRolls the transaction back if it has not already been committed or rolled back, so leaving the scope because of an exception discards the recorded actions instead of applying them. Call UndoRedoTransaction.CommitAsync to keep them.
net10.0
public ValueTask DisposeAsync()net11.0
public ValueTask DisposeAsync()Returns
Meziantou.Framework.UndoRedo.IUndoRedoAction.ExecuteAsync(CancellationToken)
UndoRedoTransaction.csApplies the change encapsulated by this action.
ValueTask IUndoRedoAction.ExecuteAsync(CancellationToken cancellationToken)Meziantou.Framework.UndoRedo.IUndoRedoAction.TryToMergeAsync(IUndoRedoAction, CancellationToken)
UndoRedoTransaction.csAttempts to merge a following action into this one instead of recording it as a separate step. Useful for long chains of consecutive operations of the same kind (e.g. dragging or typing).
ValueTask<bool> IUndoRedoAction.TryToMergeAsync(IUndoRedoAction followingAction, CancellationToken cancellationToken)Parameters
followingActionIUndoRedoAction- The action recorded right after this one.
cancellationTokenCancellationToken- A token to cancel the operation.
Returns
ValueTask<bool> true if followingAction was merged into this action; otherwise false.
Remarks
followingAction is in the same applied state as this action: both are already applied at the top level and inside an TransactionExecutionMode.Immediate transaction, and neither is applied inside a TransactionExecutionMode.Deferred one. An implementation must therefore absorb followingAction's effect without applying it.
Returning true discards followingAction: it is never executed nor reverted by the manager again, so this action becomes responsible for applying and reverting both effects from its own IUndoRedoAction.ExecuteAsync and IUndoRedoAction.UnExecuteAsync.
Meziantou.Framework.UndoRedo.IUndoRedoAction.UnExecuteAsync(CancellationToken)
UndoRedoTransaction.csReverts the change previously applied by IUndoRedoAction.ExecuteAsync.
ValueTask IUndoRedoAction.UnExecuteAsync(CancellationToken cancellationToken)RollbackAsync(CancellationToken)
UndoRedoTransaction.csRolls back the transaction, reverting any actions that were already executed.
public ValueTask RollbackAsync(CancellationToken cancellationToken = default)Parameters
cancellationTokenCancellationToken- A token to cancel the operation.
Returns
Exceptions
InvalidOperationException- The transaction is already completed, it is not the innermost open transaction, or an action is currently executing.
AggregateException- An action failed to revert and re-applying the actions that were already reverted failed too.
Remarks
The transaction stays open if the rollback fails, so it can be retried once the cause is resolved.