Class MutationViewModel<TArgs, TData>
- Namespace
- DotNetQuery.Mvvm
- Assembly
- DotNetQuery.Mvvm.dll
An INotifyPropertyChanged view model wrapping an IMutation<TArgs, TData> for MVVM-based UI frameworks (MAUI, WPF, WinUI, UNO, Avalonia). Exposes the mutation state as bindable properties and marshals all change notifications onto the UI thread via an IUiDispatcher.
The view model holds a live subscription to State for its entire lifetime. Dispose the view model when its page is torn down.
Double-submit protection: ExecuteCommand, Execute(TArgs), and every command returned by ToCommand<TParam>(Func<TParam, TArgs>, Func<TParam, bool>?) read CurrentState directly — not the dispatcher-applied CurrentState below — before starting a run. That closes the gap between a click starting a run and the resulting state reaching this view model one dispatcher hop later, and it also disables these commands when a run was started directly on a shared Mutation by something other than this view model.
public class MutationViewModel<TArgs, TData> : BindableBase, INotifyPropertyChanged, IDisposable
Type Parameters
TArgsThe type of the arguments passed to the mutator.
TDataThe type of the data returned on success.
- Inheritance
-
MutationViewModel<TArgs, TData>
- Implements
- Inherited Members
Constructors
MutationViewModel(IMutation<TArgs, TData>, IUiDispatcher?)
Wraps an existing mutation. The view model does not take ownership:
Dispose() releases only the view model's own state subscription,
and the caller remains responsible for disposing mutation.
public MutationViewModel(IMutation<TArgs, TData> mutation, IUiDispatcher? dispatcher = null)
Parameters
mutationIMutation<TArgs, TData>The mutation to wrap.
dispatcherIUiDispatcherThe UI-thread dispatcher. When
null, Current is captured; construct the view model on the UI thread or pass a dispatcher explicitly.
MutationViewModel(IQueryClient, MutationOptions<TArgs, TData>, IUiDispatcher?)
Creates a new mutation via CreateMutation<TArgs, TData>(MutationOptions<TArgs, TData>) and wraps it. The view model owns the created mutation and disposes it in Dispose(). This is the recommended path for page view models that receive an IQueryClient through dependency injection.
public MutationViewModel(IQueryClient client, MutationOptions<TArgs, TData> options, IUiDispatcher? dispatcher = null)
Parameters
clientIQueryClientThe query client used to create the mutation.
optionsMutationOptions<TArgs, TData>The mutation options.
dispatcherIUiDispatcherThe UI-thread dispatcher. When
null, Current is captured; construct the view model on the UI thread or pass a dispatcher explicitly.
Properties
CancelCommand
Triggers Cancel(). Enabled only while a run is in flight.
public ICommand CancelCommand { get; }
Property Value
CurrentState
The raw state snapshot, for bindings and converters that need the whole state.
public MutationState<TData> CurrentState { get; }
Property Value
- MutationState<TData>
Data
The data returned by the most recent successful execution. null until then.
public TData? Data { get; }
Property Value
- TData
Error
The exception from the most recent failed execution. null when not in a failure state.
public Exception? Error { get; }
Property Value
ExecuteCommand
Triggers a run with a object? parameter cast strictly to TArgs.
Disabled while a run is already in flight. See the type-level remarks for the double-submit
protection this and Execute(TArgs) share.
public ICommand ExecuteCommand { get; }
Property Value
HasData
true when Data is available.
public bool HasData { get; }
Property Value
HasError
true when Error is not null.
public bool HasError { get; }
Property Value
IsFailure
true when the most recent execution failed.
public bool IsFailure { get; }
Property Value
IsIdle
true when the mutation has not yet executed, or has been reset.
public bool IsIdle { get; }
Property Value
IsRunning
true while an execution is in flight.
public bool IsRunning { get; }
Property Value
IsSuccess
true when the most recent execution succeeded.
public bool IsSuccess { get; }
Property Value
Mutation
The wrapped mutation — the escape hatch for members without a bindable counterpart (SetEnabled(bool), or direct Rx composition via Success, Failure, Settled).
public IMutation<TArgs, TData> Mutation { get; }
Property Value
- IMutation<TArgs, TData>
Status
The current lifecycle status of the mutation.
public MutationStatus Status { get; }
Property Value
Methods
Dispose()
Releases the view model's state subscription and disposes the wrapped mutation if this view model created it.
public void Dispose()
Dispose(bool)
Releases resources. Override in derived view models to dispose additional state; always call the base implementation.
protected virtual void Dispose(bool disposing)
Parameters
Execute(TArgs)
Triggers a run with args, unless CurrentState
already reports Running — see the type-level remarks.
public void Execute(TArgs args)
Parameters
argsTArgsThe arguments to pass to the mutator.
ToCommand(Func<TArgs>, Func<bool>?)
Wraps this mutation as a parameterless command. The mutator's arguments come from
args — typically reading bound properties on the owning page view model —
rather than from the command parameter. The returned command shares this view model's
double-submit protection, and its CanExecute(object) additionally consults
canExecute when supplied.
public IMutationCommand ToCommand(Func<TArgs> args, Func<bool>? canExecute = null)
Parameters
argsFunc<TArgs>Produces the mutator's arguments at the moment the command executes.
canExecuteFunc<bool>An additional predicate. When
null, only the running gate applies. Call RaiseCanExecuteChanged() on the returned command when an input this predicate reads changes outside the mutation's own state.
Returns
ToCommand<TParam>(Func<TParam, TArgs>, Func<TParam, bool>?)
Wraps this mutation as a command whose parameter is TParam, mapped to
TArgs via map. The returned command shares this view
model's double-submit protection, and its CanExecute(object) additionally
consults canExecute when supplied.
public IMutationCommand ToCommand<TParam>(Func<TParam, TArgs> map, Func<TParam, bool>? canExecute = null)
Parameters
mapFunc<TParam, TArgs>Maps the command parameter to the mutator's arguments.
canExecuteFunc<TParam, bool>An additional predicate evaluated with the command parameter. When
null, only the running gate applies. Call RaiseCanExecuteChanged() on the returned command when an input this predicate reads changes outside the mutation's own state.
Returns
Type Parameters
TParam
Events
StateChanged
Raised on the UI thread after every PropertyChanged notification for an applied state.
public event EventHandler? StateChanged