Toast
Overview
Section titled “Overview”Toast collapses the web contract’s Root/Content/Title/Description/Action/Close part tree into one
lookless Control, NaviusToast, plus named template parts. A consumer never constructs
NaviusToast directly: a ToastManager (a plain, framework-agnostic C# queue with a visibility
limit and per-toast auto-dismiss timers) is bound to a NaviusToastViewport placed in a corner of
the window, and ToastManager.Add(ToastOptions) enqueues a toast that the viewport creates,
positions, animates, and dismisses on the manager’s behalf.
xmlns:navius="clr-namespace:Navius.Wpf.Primitives.Controls;assembly=Navius.Wpf.Primitives"xmlns:toast="clr-namespace:Navius.Wpf.Primitives.Controls.Toast;assembly=Navius.Wpf.Primitives"
<Grid> <!-- app content --> <navius:NaviusButton Content="Save" Click="OnSaveClick" />
<toast:NaviusToastViewport x:Name="Toasts" Manager="{Binding ToastManager}" Alignment="BottomRight" /></Grid>The Manager is a plain C# object, typically created once in code-behind or a view model
(new ToastManager(limit: 3)) and bound or assigned to the viewport. Enqueue a toast with
Manager.Add(new ToastOptions { Title = "Saved", Description = "Your changes were saved." });
the call returns a ToastHandle for later Update/Dismiss/Pause/Resume.
Properties
Section titled “Properties”| Property | Type | Default | From | Description |
|---|---|---|---|---|
Manager |
ToastManager? |
null |
NaviusToastViewport |
The manager whose VisibleToasts this viewport renders. Assign once, usually via binding. |
Alignment |
NaviusToastAlignment |
BottomRight |
NaviusToastViewport |
Which corner or top/bottom-center edge of the host the stack anchors to. No web equivalent by name: the web contract has a single fixed-position viewport styled by the consumer’s own CSS. |
Gap |
double |
16 |
NaviusToastViewport |
Spacing, in DIPs, between stacked toasts. Matches the web contract’s ToastProviderContext.Gap default. |
Index |
int (attached, read-only) |
- |
NaviusToastViewport |
Published per visible toast, 0 = frontmost/newest, for a custom template to key off; the viewport itself positions toasts directly and does not read this back. |
OffsetY |
double (attached, read-only) |
- |
NaviusToastViewport |
Cumulative offset, in DIPs, from the anchored edge; published alongside Index. |
Title |
string? |
null |
NaviusToast |
Mirrors ToastOptions.Title. Changing it while loaded re-raises the UIA notification. |
Description |
string? |
null |
NaviusToast |
Mirrors ToastOptions.Description. |
Type |
ToastType |
Default |
NaviusToast |
Default | Success | Error | Loading; drives the default template’s visual variant. |
Priority |
ToastPriority |
Low |
NaviusToast |
Low maps to UIA LiveSetting.Polite (the web’s role="status"); High maps to Assertive (role="alert"). |
ActionLabel |
string? |
null |
NaviusToast |
Label for the action template part, when present. |
ActionAltText |
string |
"" |
NaviusToast |
Required plain-text description of the action for assistive tech. |
ShowCloseButton |
bool |
true |
NaviusToast |
Whether the close template part renders. |
Title / Description / Type / Priority / Duration / Action |
see ToastOptions |
see below | ToastOptions |
Per-toast configuration record passed to ToastManager.Add/Update. Duration (TimeSpan?, null) falls back to ToastManager.DefaultDuration; a non-positive value is sticky (no auto-dismiss). Action (ToastActionSpec?, null) pairs a label, an alt-text string, and a click handler. |
Limit |
int |
1 |
ToastManager |
Max simultaneously-visible toasts; the rest queue and promote, oldest-queued first, as slots free. Live-mutable: changing it re-evaluates the queue and raises Changed immediately. |
DefaultDuration |
TimeSpan |
5000ms |
ToastManager |
Constructor-only default auto-dismiss duration for toasts that don’t set their own Duration. |
Methods
Section titled “Methods”| Method | Description |
|---|---|
ToastManager.Add(ToastOptions) -> ToastHandle |
Enqueues a new toast; returns a handle to update, dismiss, pause, or resume it later. |
ToastHandle.Update(ToastOptions) |
Replaces the toast’s options wholesale and rearms its auto-dismiss timer against the new effective duration (e.g. flipping a loading toast to success). |
ToastHandle.Dismiss() |
Removes the toast immediately. |
ToastHandle.Pause() / Resume() |
Ref-counted pause/resume of the toast’s auto-dismiss timer; multiple sources (hover, focus-within) can each pause without one source’s resume prematurely restarting the countdown. |
ToastManager.Clear() |
Removes every tracked toast immediately. |
ToastManager.PauseAll() / ResumeAll() |
Pause/resume every currently-visible toast’s timer (e.g. on window deactivation/activation). |
Events
Section titled “Events”| Event | Signature | Fires when |
|---|---|---|
NaviusToast.CloseRequested |
RoutedEventHandler |
Escape is pressed on a focused toast, or the close template part is clicked; the viewport dismisses the toast via ToastHandle.Dismiss(). |
NaviusToast.ActionRequested |
RoutedEventHandler |
The action template part is clicked; the viewport runs the configured ToastActionSpec.OnClick and then dismisses the toast. |
ToastManager.Changed |
Action (plain CLR event) |
Raised after Add/Update/Dismiss/Clear/Limit changes; NaviusToastViewport subscribes to resync its visuals. |
Keyboard interactions
Section titled “Keyboard interactions”| Key | Behavior |
|---|---|
Escape (toast focused) |
Raises CloseRequested; the viewport dismisses the toast. |
F6 (anywhere in the window, at least one toast visible) |
Focuses the viewport. Hardcoded: the web contract’s configurable Hotkey/LabelTemplate are not ported. |
Tab |
Native tab order; each toast is focusable, so the visible stack is reachable. |
Swipe-to-dismiss is not implemented in this port (see Web deltas).
UIA mechanism
Section titled “UIA mechanism”NaviusToastAutomationPeer (a FrameworkElementAutomationPeer) reports
AutomationControlType.Group (no closer 1:1 UIA control type exists for a transient status/alert
region) and GetLiveSettingCore() returns Assertive for High priority, Polite for Low, the
UIA analogue of the web’s role="alert"/role="status". On load, and whenever Title or
Description changes while loaded, NaviusToast additionally calls
AutomationPeer.RaiseNotificationEvent directly, a more direct and better-supported mechanism than
duplicating text into a hidden aria-live region; GetLiveSettingCore’s value remains the fallback
for OS/AT combinations where the notification event isn’t observed (RaiseNotificationEvent
requires Windows 10 version 1709+). Covered by
NaviusToastAutomationPeer_LiveSetting_MatchesPriority and a dedicated Escape-key regression test
in ToastTests.cs (31 tests total, most running as plain [Fact]s against a manual-advance timer
double with no live Dispatcher needed).
Web deltas
Section titled “Web deltas”- The web’s five-part tree (Root/Content/Title/Description/Action/Close) plus a separate
Provider/Portal collapses into one lookless
NaviusToast(withPART_Close/PART_Actiontemplate parts) rendered byNaviusToastViewport; there is noNaviusToastProviderorNaviusToastPortal, since there is no cascading-context/DI surface or portal concept to replicate. - Live-region mechanism replaced outright: instead of duplicating announcement text into hidden
aria-liveregions, the WPF port raises a genuine UIA notification event (RaiseNotificationEvent), withGetLiveSettingCorekept only as a fallback for older OS/AT combinations. F6is hardcoded rather than configurable: the web’sHotkey: string[]andLabelTemplateparameters are not ported. The parity task’s own accessibility audit found the web’s documented hotkey claim inaccurate, so this port only commits to the one hotkey it actually tests.- Swipe-to-dismiss (
SwipeDirection/SwipeThreshold) is not implemented: hover-pause and Escape/close-button dismiss cover this milestone’s interaction surface; drag-to-dismiss was scoped out as a separately-testable follow-up. NaviusToastPositioner/NaviusToastArroware retired: confirmed unwired stubs upstream (the web contract itself notes they are “not used by the primary viewport-stacked toast”), and no anchored-toast variant exists in either port.- Queueing is promotion-based, not just eviction-based: the first
Limittoasts by insertion order stay visible, and anything beyond that queues until an earlier toast is dismissed and a slot promotes the next-oldest queued toast.Limitis also live-mutable at runtime, a detail the web contract’sProvider.Limitparameter does not specify either way. - Stacking and positioning are C#-computed (
Reflow()setsCanvas.Top/Bottom/Left/Rightper toast from measuredActualHeightplusGap) rather than CSS custom properties;NaviusToastViewport.Index/OffsetYare read-only attached properties published for a custom template, mirroring the web’s “Content publishes vars, never computes a transform” split.
Captures
Section titled “Captures”The Toast Gallery page rendered at the pinned commit, in each theme.


