Dialogs
Add Plugin.Uno.MVVMExpress.Dialogs and call UseDialogs() on UseUnoMvvmExpress. Inject IDialogs for alerts/confirm and INotifier for toast. UnoDialogs hops to IMainThread like UnoNotifier. UnoToastPresenter draws an overlay — it never wraps or replaces Window.Content, so ResetAsync cannot restore a stale tree. Do not replace Window.Content with a toast host. Tests use FakeDialogs.
public sealed class ProductEditViewModel : PageViewModel
{
public ProductEditViewModel(IDialogs dialogs, INotifier notifier)
: base(navigator: null, dialogs)
{
}
public async Task DeleteAsync(CancellationToken cancellationToken)
{
var ok = await Dialogs!.ConfirmAsync(
"Delete product",
"This cannot be undone.",
accept: "Delete",
cancel: "Cancel",
cancellationToken);
if (!ok)
{
return;
}
await _catalog.DeleteAsync(_productId, cancellationToken);
await Notifier.ToastAsync("Deleted", cancellationToken: cancellationToken);
}
}