Table of Contents

Class QueryViewModel<TArgs, TData>

Namespace
DotNetQuery.Mvvm
Assembly
DotNetQuery.Mvvm.dll

An INotifyPropertyChanged view model wrapping an IQuery<TArgs, TData> for MVVM-based UI frameworks (MAUI, WPF, WinUI, UNO, Avalonia). Exposes the query 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 — this is what keeps the underlying cache entry retained and triggers deferred stale fetches. Dispose the view model when its page is torn down; a forgotten dispose keeps the cache entry alive indefinitely.

public class QueryViewModel<TArgs, TData> : BindableBase, INotifyPropertyChanged, IDisposable where TData : class

Type Parameters

TArgs

The type of the parameters passed to the fetcher.

TData

The type of data returned by the query. Constrained to reference types.

Inheritance
QueryViewModel<TArgs, TData>
Implements
Inherited Members

Constructors

QueryViewModel(IQueryClient, QueryOptions<TArgs, TData>, IUiDispatcher?)

Creates a new query observer via CreateQuery<TArgs, TData>(QueryOptions<TArgs, TData>) and wraps it. The view model owns the created query and disposes it in Dispose(). This is the recommended path for page view models that receive an IQueryClient through dependency injection.

public QueryViewModel(IQueryClient client, QueryOptions<TArgs, TData> options, IUiDispatcher? dispatcher = null)

Parameters

client IQueryClient

The query client used to create the observer.

options QueryOptions<TArgs, TData>

The query 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.

QueryViewModel(IQuery<TArgs, TData>, IUiDispatcher?)

Wraps an existing query. The view model does not take ownership: Dispose() releases only the view model's own state subscription, and the caller remains responsible for disposing query.

public QueryViewModel(IQuery<TArgs, TData> query, IUiDispatcher? dispatcher = null)

Parameters

query IQuery<TArgs, TData>

The query 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.

Properties

CancelCommand

Triggers Cancel(). Enabled only while a fetch 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 QueryState<TData> CurrentState { get; }

Property Value

QueryState<TData>

Data

The data returned by the most recent successful fetch; null while fetching. Bind to DisplayData to keep showing stale data during background re-fetches.

public TData? Data { get; }

Property Value

TData

DisplayData

Data, falling back to LastData while a re-fetch is in progress — the stale-while-revalidate binding target, mirroring the Blazor <Transition> component.

public TData? DisplayData { get; }

Property Value

TData

Error

The exception from the most recent failed fetch. null when not in a failure state.

public Exception? Error { get; }

Property Value

Exception

HasData

true when Data is not null.

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 fetch failed.

public bool IsFailure { get; }

Property Value

bool

IsFetching

true while any fetch is in flight, including background re-fetches. See IsLoading for the first-load-only variant.

public bool IsFetching { get; }

Property Value

bool

IsIdle

true when the query is idle.

public bool IsIdle { get; }

Property Value

bool

IsLoading

true only during the first load — fetching with no current or previous data to show. Bind a full-page loading indicator to this and a subtle refresh indicator to IsFetching.

public bool IsLoading { get; }

Property Value

bool

IsSuccess

true when the most recent fetch succeeded.

public bool IsSuccess { get; }

Property Value

bool

LastData

The data from the previous successful fetch, carried across fetches and failures.

public TData? LastData { get; }

Property Value

TData

Query

The wrapped query — the escape hatch for members without a bindable counterpart (Invalidate(), PrefetchAsync(TArgs, CancellationToken), Select<TResult>(Func<TData, TResult>, IEqualityComparer<TResult>?), or direct Rx composition).

public IQuery<TArgs, TData> Query { get; }

Property Value

IQuery<TArgs, TData>

RefetchCommand

Triggers Refetch(). Disabled while a fetch is in flight.

public ICommand RefetchCommand { get; }

Property Value

ICommand

Status

The current lifecycle status of the query.

public QueryStatus Status { get; }

Property Value

QueryStatus

Methods

Dispose()

Releases the view model's state subscription — which lets the cache entry's eviction clock start — and disposes the wrapped query 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().

SetArgs(TArgs)

Sets the args that drive the next fetch. When args change, the query switches to the cache entry for the newly derived key and triggers a fetch if the query is enabled.

public void SetArgs(TArgs args)

Parameters

args TArgs

SetData(TData)

Directly writes data into the active cache entry as a success state, bypassing any in-flight fetch. Stamps the entry as fresh so stale-time is respected and an immediate re-fetch is not triggered. Useful for applying optimistic updates before a mutation completes.

public void SetData(TData data)

Parameters

data TData

SetEnabled(bool)

Enables or disables the query. When false, fetching is suspended even if the query is invalidated or new args are pushed. Pass true to resume; the query will immediately re-evaluate its active key and trigger a fetch if one is pending.

public void SetEnabled(bool enabled)

Parameters

enabled bool

Events

StateChanged

Raised on the UI thread after every PropertyChanged notification for an applied state. Use this — instead of a second raw subscription to Query's state — for page-specific work such as syncing an ObservableCollection<T> from DisplayData.

public event EventHandler? StateChanged

Event Type

EventHandler