Table of Contents

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

TArgs

The type of the arguments passed to the mutator.

TData

The 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

mutation IMutation<TArgs, TData>

The mutation to wrap.

dispatcher IUiDispatcher

The 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

client IQueryClient

The query client used to create the mutation.

options MutationOptions<TArgs, TData>

The mutation options.

dispatcher IUiDispatcher

The 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

ICommand

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

Exception

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

ICommand

HasData

true when Data is available.

public bool HasData { get; }

Property Value

bool

HasError

true when Error is not null.

public bool HasError { get; }

Property Value

bool

IsFailure

true when the most recent execution failed.

public bool IsFailure { get; }

Property Value

bool

IsIdle

true when the mutation has not yet executed, or has been reset.

public bool IsIdle { get; }

Property Value

bool

IsRunning

true while an execution is in flight.

public bool IsRunning { get; }

Property Value

bool

IsSuccess

true when the most recent execution succeeded.

public bool IsSuccess { get; }

Property Value

bool

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

MutationStatus

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

disposing bool

true when called from Dispose().

Execute(TArgs)

Triggers a run with args, unless CurrentState already reports Running — see the type-level remarks.

public void Execute(TArgs args)

Parameters

args TArgs

The 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

args Func<TArgs>

Produces the mutator's arguments at the moment the command executes.

canExecute Func<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

IMutationCommand

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

map Func<TParam, TArgs>

Maps the command parameter to the mutator's arguments.

canExecute Func<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

IMutationCommand

Type Parameters

TParam

Events

StateChanged

Raised on the UI thread after every PropertyChanged notification for an applied state.

public event EventHandler? StateChanged

Event Type

EventHandler