Menu
Overview
Section titled “Overview”Menu is a trigger-anchored dropdown built entirely on native WPF menu controls (a ToggleButton
trigger, a ContextMenu popup, MenuItem-derived items), so roving focus, typeahead, mnemonics,
and submenu opening/closing are inherited rather than reimplemented. The web contract’s 17-part
anatomy (Root/Trigger/Portal/Positioner/Popup/Arrow/Item/CheckboxItem/ItemIndicator/Group/
GroupLabel/RadioGroup/RadioItem/Separator/Sub/SubTrigger/SubContent) collapses onto 8 WPF classes,
with submenus expressed as ordinary native MenuItem nesting.
xmlns:menu="clr-namespace:Navius.Wpf.Primitives.Controls.Menus;assembly=Navius.Wpf.Primitives"
<StackPanel> <StackPanel.Resources> <menu:NaviusMenuPopup x:Key="FileMenu"> <menu:NaviusMenuItem Header="New" Command="ApplicationCommands.New" /> <menu:NaviusMenuCheckboxItem Header="Word wrap" Checked="{Binding WordWrap, Mode=TwoWay}" /> <menu:NaviusMenuSeparator /> <menu:NaviusMenuItem Header="Recent"> <menu:NaviusMenuItem Header="Document 1.txt" /> </menu:NaviusMenuItem> </menu:NaviusMenuPopup> </StackPanel.Resources>
<menu:NaviusMenuTrigger Content="File" Menu="{StaticResource FileMenu}" /></StackPanel>A NaviusMenuItem with child NaviusMenuItems automatically becomes a submenu header; there is
no separate Sub/SubTrigger/SubContent type.
Properties
Section titled “Properties”| Property | Type | Default | From | Description |
|---|---|---|---|---|
Menu |
NaviusMenuPopup? |
null |
NaviusMenuTrigger |
The popup this trigger opens and closes. |
IsChecked |
bool? |
false |
ToggleButton |
Doubles as the contract’s data-popup-open; toggling opens/closes Menu with itself as PlacementTarget. The popup’s own Closed event resets it back to false for every dismissal path. |
Side |
PlacementSide |
Bottom |
NaviusMenuPopup |
Placement side; combined with Align via a CustomPopupPlacementCallback (native PlacementMode has no side+align axis). |
Align |
PlacementAlign |
Center |
NaviusMenuPopup |
Placement alignment. |
SideOffset |
double |
0 |
NaviusMenuPopup |
- |
AlignOffset |
double |
0 |
NaviusMenuPopup |
- |
Loop |
bool |
false |
NaviusMenuPopup |
Kept for parameter-surface parity; native MenuItem/ContextMenu arrow-key navigation has no wrap-around switch, so it has no behavioral effect. |
TextValue |
string? |
null |
NaviusMenuItemBase |
Overrides the text typeahead matches against; writes straight onto native TextSearch.Text. |
Checked |
bool? |
false |
NaviusMenuCheckboxItem |
Tri-state API surface (null = indeterminate); registers a default of false, not null (see Web deltas). Mirrored into native IsChecked (indeterminate maps to false). |
IsIndeterminate |
bool |
false |
NaviusMenuCheckboxItem |
Drives the dash glyph; set from Checked == null. |
Value |
string |
"" |
NaviusMenuRadioItem |
This item’s value within its group. |
GroupName |
string |
"" |
NaviusMenuRadioItem |
Items sharing GroupName under the same owning menu/submenu are mutually exclusive; not WPF’s attached RadioButton.GroupName. |
Content |
object |
- |
ContentControl |
NaviusMenuGroupLabel’s heading text; non-focusable, safely skipped by native item roving like Separator is. |
Events
Section titled “Events”| Event | Signature | Fires when |
|---|---|---|
Select |
RoutedEventHandler |
An item, checkbox item, or radio item is activated (click or Enter/Space); cancelable, PreventDefault() keeps the menu open instead of closing it. |
CheckedChanged |
RoutedEventHandler |
NaviusMenuCheckboxItem.Checked toggles, from the DP-change callback so it fires on every change, programmatic or click-driven. |
Keyboard interactions
Section titled “Keyboard interactions”| Key | Behavior |
|---|---|
ArrowDown / ArrowUp (open menu) |
Native roving focus between enabled MenuItem siblings (inherited, not reimplemented). |
Home |
Native roving to the first enabled item (inherited). |
| A printable character | Native first-letter typeahead via TextSearch.Text (inherited). |
ArrowRight (ArrowLeft in rtl) / Enter / Space (on a submenu header) |
Opens the submenu (native MenuItem.Role == SubmenuHeader handling). |
ArrowLeft (ArrowRight in rtl) (inside a submenu) |
Closes only that submenu (native). |
Enter / Space (on Item / CheckboxItem / RadioItem) |
Activates the item: raises Select, then closes the owning ContextMenu unless PreventDefault() was called. |
Escape |
Closes the open ContextMenu (native Popup dismissal). |
UIA mechanism
Section titled “UIA mechanism”NaviusMenuPopup ships no custom automation peer; it inherits the native ContextMenu
automation peer. NaviusMenuItem/NaviusMenuCheckboxItem/NaviusMenuRadioItem inherit
MenuItemAutomationPeer (AutomationControlType.MenuItem); when IsCheckable is true the peer
implements IToggleProvider, exercised by the unit suite’s MenuItemAutomationPeer
IToggleProvider/ToggleState test. No custom peer was added anywhere in this family.
Web deltas
Section titled “Web deltas”- 17 web parts collapse onto 8 WPF classes.
NaviusMenuPortalis a no-op (WPF popups already float in their own window layer);NaviusMenuPositionerfolds ontoSide/Align/SideOffset/AlignOffsetonNaviusMenuPopupdirectly. NaviusMenuArrowis not implemented (deferred).NaviusMenuGroupandNaviusMenuRadioGrouphave no wrapper type: a transparent non-MenuItemwrapper would break nativeMenuItem/ContextMenuarrow-key roving, which only navigatesMenuItem-typed containers. Grouping is visual-only (NaviusMenuGroupLabelplus item ordering); radio mutual exclusion is aGroupNameproperty scoped to the item’s immediate owning menu/submenu, not a wrapping element.NaviusMenuSub/SubTrigger/SubContentcollapse into nativeMenuItemsubmenu nesting.- The dismiss-hook superset (
OnOpenAutoFocus/OnCloseAutoFocus/OnEscapeKeyDown/OnPointerDownOutside/OnFocusOutside/OnInteractOutside) is not implemented: nativeContextMenu/Popupalready dismiss on outside-click and Escape. Modalis not implemented (no scroll-lock equivalent).Side/Aligncover the contract’s 4-side x 3-align matrix through aCustomPopupPlacementCallbackwith flip/shift disabled, so placement is a single fixed choice, not collision-aware like the web positioner.Loophas no behavioral effect: nativeMenuItem/ContextMenuarrow-key navigation has no public wrap-around switch.- Known residual (M6 audit):
NaviusMenuCheckboxItem.Checkedregisters a default offalse, notnull(indeterminate) as the web contract specifies. A default-constructed checkbox item starts unchecked rather than indeterminate, and the dash glyph (driven by the separateIsIndeterminateflag, itself defaultingfalse) does not show untilCheckedis explicitly set. Low impact since indeterminate is reachable only programmatically in the web contract too. - Namespace note: the folder is
Controls/Menu/, but the C# namespace isNavius.Wpf.Primitives.Controls.Menus(plural), to avoid a naming collision with the sibling Menubar family’s own use of bareMenu.
Captures
Section titled “Captures”The Menu Gallery page rendered at the pinned commit, in each theme.


