Dialog
Overview
Section titled “Overview”Dialog is a lookless ContentControl whose own template is the backdrop plus panel;
the web family’s Root/Trigger/Portal/Backdrop/Popup/Title/Description/Close parts are
folded into this one control plus a CloseCommand binding. It renders inside the
window’s NaviusOverlayLayer (the WPF analogue of the web’s document.body portal
target) and drives modality, Escape and outside-click dismissal, and focus cycling
through the shared OverlayStack.
xmlns:navius="clr-namespace:Navius.Wpf.Primitives.Controls;assembly=Navius.Wpf.Primitives"xmlns:overlay="clr-namespace:Navius.Wpf.Primitives.Controls.OverlaySurface;assembly=Navius.Wpf.Primitives"xmlns:dialog="clr-namespace:Navius.Wpf.Primitives.Controls.Dialog;assembly=Navius.Wpf.Primitives"
<Grid> <!-- app content --> <navius:NaviusButton Content="Open" Click="OnOpenDialog" />
<!-- one layer per window, stretched over the root --> <overlay:NaviusOverlayLayer> <dialog:NaviusDialog x:Name="Confirm" Title="Confirm change" Description="This updates the shared settings."> <StackPanel> <TextBlock Text="Apply the change?" /> <navius:NaviusButton Content="Close" Command="overlay:NaviusOverlaySurfaceBase.CloseCommand" /> </StackPanel> </dialog:NaviusDialog> </overlay:NaviusOverlayLayer></Grid>A dialog is declared as a direct XAML child of the layer (it is never re-parented at
runtime) and stays Collapsed until opened via IsOpen, Open(), or a binding. A
window with no NaviusOverlayLayer still parses; opening then logs a
Trace.TraceWarning and reverts IsOpen to false.
Properties
Section titled “Properties”| Property | Type | Default | From | Description |
|---|---|---|---|---|
IsOpen |
bool |
false |
NaviusOverlaySurfaceBase |
Open state. Two-way bindable by default. Setting it engages or disengages the overlay; a canceled Closing reverts it to true so the DP never desyncs from the live overlay. |
Title |
string? |
null |
NaviusOverlaySurfaceBase |
Accessible name. Applied via AutomationProperties.Name on engage. |
Description |
string? |
null |
NaviusOverlaySurfaceBase |
Accessible help text. Applied via AutomationProperties.HelpText on engage. |
Modal |
bool |
true |
NaviusDialog |
When true: focus is trapped, the backdrop shows, outside interaction is blocked. When false: no trap, no backdrop, outside content stays interactive. |
CloseOnOutsideClick |
bool |
true |
NaviusDialog |
Whether a press outside the panel dismisses the dialog. Independently overridable, matching the web contract’s optional outside dismissal. |
Content |
object |
- |
ContentControl |
The dialog body. |
Methods
Section titled “Methods”| Method | Description |
|---|---|
Open() |
Sets IsOpen to true via SetCurrentValue, preserving an existing two-way binding. |
Close() |
Sets IsOpen to false via SetCurrentValue, preserving an existing two-way binding. |
Commands
Section titled “Commands”| Command | Description |
|---|---|
NaviusOverlaySurfaceBase.CloseCommand |
Bind any element inside Content to request a close, mirroring the web’s NaviusDialogClose part. |
Events
Section titled “Events”| Event | Signature | Fires when |
|---|---|---|
Opened |
EventHandler |
The overlay has engaged: pushed onto the OverlayStack, enter animation started. |
Closing |
EventHandler<OverlayClosingEventArgs> |
A close was requested (Escape, outside press, CloseCommand, or IsOpen = false). Cancelable: set Cancel to keep the dialog open; IsOpen then stays true. |
Closed |
EventHandler |
The exit animation completed and the surface left its layer. |
Keyboard interactions
Section titled “Keyboard interactions”| Key | Behavior |
|---|---|
Escape |
Closes the dialog. Routed through the window-level OverlayStack PreviewKeyDown hook; fixed on (not configurable), matching the parity contract. |
Tab / Shift + Tab |
Cycles focus among the dialog’s focusable descendants while modal, via KeyboardNavigationMode.Cycle applied by the OverlayStack focus trap. |
UIA mechanism
Section titled “UIA mechanism”NaviusDialogAutomationPeer (a FrameworkElementAutomationPeer) reports
AutomationControlType.Window and overrides IsDialogCore() to return true, the
native mapping for the web’s role="dialog". On engage, Title and Description are
applied as AutomationProperties.Name and AutomationProperties.HelpText, which the
default peer surfaces without further overrides; the same treatment applies uniformly
across Dialog, AlertDialog, and Drawer. Focus moves to the first focusable descendant
on open and is restored on close while modal. The unit suite exercises this against
real windows, including the M6 regression for a canceled Closing keeping IsOpen,
the surface, and the session consistent.
Web deltas
Section titled “Web deltas”- One control instead of eight parts: the web’s Root/Trigger/Portal/Backdrop/Popup/
Title/Description/Close anatomy is folded into
NaviusDialogplusCloseCommand, following the same shape this codebase uses forNaviusRadioGroupandNaviusCheckboxGroup. There is no discrete Trigger element; any button or binding opens the dialog. NaviusOverlayLayerreplaces the web’s CSS-selectorContainerparameter: a window registers at most one layer, and surfaces are declared as its direct XAML children.System.Windows.Controls.Primitives.Popuphosting was rejected because aPopuprenders through its own top-level surface, invisible to theOverlayStack’s window-level key and outside-press routing.TitleandDescriptionare string properties feeding UIA name and help text, not mounted sub-elements with generated id wiring (aria-labelledbyandaria-describedbyhave no WPF equivalent).- Enter and exit transitions are a fixed 150ms opacity fade via
DoubleAnimation(exit completion is what unmounts, so it is never truncated); the web drives these fromdata-starting-styleanddata-ending-styleCSS hooks. The primitive does not reference Navius.Wpf.Motion. CloseOnEscapeis fixedtrueand not exposed (the web family never overrides it either);CloseOnOutsideClickis exposed as a property.- Known residual (M6 audit): a non-modal dialog (
Modal="false") does not restore focus to the previously focused element on close, because theOverlayStackonly captures a restore target when trapping focus. The web contract restores focus in both paths.
Captures
Section titled “Captures”The Dialog Gallery page rendered at the pinned commit, in each theme.


