WPF Standard Control Demo App › Menu
Menu Menu
Menu is a bar of headers, each opening a list of commands. Each entry is a MenuItem, which can hold its own submenu.
Which keys move into the menu
IsMainMenu on a Menu decides whether pressing Alt moves into the menu; the default is True. With a TextBox focused, a real Alt highlighted the first header and took the focus with True, and did nothing with False. Because the default is True, set IsMainMenu="False" on any other Menu that should not receive the Alt and F10 notifications.
The documentation says IsMainMenu controls both the Alt and the F10 notifications. On the measuring machine, which uses a Japanese input method, a real F10 with the TextBox focused did nothing in either case. With True, a real F10 with a Button focused, and F10 sent to the TextBox through WPF’s input manager, both moved into the menu. The Japanese input method, which uses F10 itself, is a possible cause of the difference, but that was not verified: the input method was not turned off for the measurement.
The access key worked either way: Alt+M opened the demo app’s “Main Menu(_M)” even with False.
Item roles and header states
A Menu holds MenuItem elements, and each MenuItem’s read-only Role follows from where it is and whether it has children. In the demo app’s Role section, the four items were TopLevelHeader, SubmenuHeader, SubmenuItem, and TopLevelItem. The role changes with the children: adding a child to the TopLevelItem, which was not checkable, made it a TopLevelHeader. In the WPF source, an item takes a header role only when it has children and IsCheckable is False; a checkable item with children was not measured.
A header’s state is exposed by IsHighlighted, IsPressed, IsSubmenuOpen, and IsSuspendingPopupAnimation, all read-only except IsSubmenuOpen. Hovering with the real mouse set IsHighlighted. Pressing the button set IsPressed and opened the submenu, and releasing it cleared only IsPressed. IsSuspendingPopupAnimation was True once the submenu was open. With two headers, hovering over the second while the first was open closed the first and opened the second.
Checkable items, and keeping the submenu open
IsCheckable decides whether a click toggles IsChecked; the default is False. A real click checked the item, and a second click cleared it. Without IsCheckable, the click left it unchecked. IsChecked binds both ways with a check box: the check box followed the click, and checking the check box in code checked the item.
Checkable items are not exclusive: clicking two items in one submenu checked both. For exclusive choices, uncheck the others in code or use a bound value.
StaysOpenOnClick decides whether the submenu stays open after the item is clicked; the default is False. After a real click, the submenu closed with False and stayed open with True.
Commands, IsEnabled, and shortcut text
With Command set to ApplicationCommands.Copy and the menu opened with a real click, the item was disabled with no text selected in the TextBox, enabled with all text selected, and disabled with a Button focused. While the menu was open, the keyboard focus was on a MenuItem, but the item still followed the TextBox’s selection.
A submenu item’s IsEnabled is not up to date while its menu is closed. With the TextBox focused and nothing selected, the Copy item’s IsEnabled read True although the command’s CanExecute returned False. Once the menu was opened with a real click, the item was disabled. Call the command’s CanExecute rather than reading the item’s IsEnabled.
Icon is an image at the left, and InputGestureText a shortcut text at the right. InputGestureText is only text: “Ctrl+O” was shown, but a real Ctrl+O did not click the item. For a command with a key gesture it is filled in: the Copy item’s text was Ctrl+C without being set. With a KeyBinding on the window, a real Ctrl+O ran a command that has no key gesture of its own, but the item’s InputGestureText stayed empty. Bind the shortcut with a KeyBinding, and set InputGestureText too.
| case | measured |
|---|---|
| defaults: IsMainMenu; IsCheckable, IsChecked, StaysOpenOnClick, InputGestureText | True; False, False, False, (empty) |
| demo's Role section: the four items | TopLevelHeader, SubmenuHeader, SubmenuItem, TopLevelItem |
| a child added to TopLevelItem: its Role | TopLevelHeader |
| IsCheckable True, StaysOpenOnClick True: opened; click: checked / CheckBox / open; again | True; True / True / True; False / True |
| the CheckBox checked in code: item IsChecked | True |
| IsCheckable True, StaysOpenOnClick False: opened; click: checked / CheckBox / open; again | True; True / True / False; - |
| IsCheckable False, StaysOpenOnClick True: opened; click: checked / CheckBox / open; again | True; False / False / True; False / True |
| two checkable items, both clicked: IsChecked | True, True |
| IsMainMenu True, real Alt: highlighted / submenu open / TextBox keeps focus | True / False / False |
| IsMainMenu True, real F10: highlighted / submenu open / TextBox keeps focus | False / False / True |
| IsMainMenu True, real Alt+M: highlighted / submenu open / TextBox keeps focus | True / True / False |
| IsMainMenu False, real Alt: highlighted / submenu open / TextBox keeps focus | False / False / True |
| IsMainMenu False, real F10: highlighted / submenu open / TextBox keeps focus | False / False / True |
| IsMainMenu False, real Alt+M: highlighted / submenu open / TextBox keeps focus | True / True / False |
| IsMainMenu True, real F10, Button: highlighted / open / focus in menu | True / False / True |
| IsMainMenu True, F10 via InputManager, TextBox: highlighted / open / focus in menu | True / False / True |
| InputGestureText "Ctrl+O": shown / InputGestureText of the Copy item | shown (35.83 wide) / Ctrl+C |
| real Ctrl+O with a TextBox focused: Click count | 0 |
| Copy item, menu closed, TextBox focused, no selection: IsEnabled / CanExecute | True / False |
| opened by real click: no selection; all selected (focus); Button focused | False; True (MenuItem); False |
| Observation Target: Highlighted / Pressed / SubmenuOpen / Suspending: before; hover | False / False / False / False; True / False / False / False |
| real button down; up | True / True / True / True; True / False / True / True |
| click File: open / suspending; hover Edit: File open; Edit open / suspending | True / True; False; True / True |
| window KeyBinding Ctrl+O, real Ctrl+O: executed / item's InputGestureText | 1 / (empty) |
Roles, checkable items, the main menu, gestures, commands, and header states. Measured on .NET 10 / Windows 11.
Trying it in the demo app

The Menu page of the demo app has sections for IsMainMenu, IsCheckable with IsChecked and StaysOpenOnClick, Role, Command, Icon with InputGestureText, and a last section showing IsHighlighted, IsPressed, IsSubmenuOpen, and IsSuspendingPopupAnimation. The IsCheckable section starts both IsCheckable and StaysOpenOnClick at True and binds a check box to IsChecked two-way; the Command section uses ApplicationCommands.Copy; and the InputGestureText section shows “Ctrl+O”. The “Show Code” link under each section displays its XAML. The following XAML is the IsCheckable section (MenuUsageControl.xaml), with the styles and the surrounding GroupBoxes left out and the namespace declarations added:
<StackPanel xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<CheckBox x:Name="IsCheckableCheckBox" Content="IsCheckable" IsChecked="True" />
<CheckBox x:Name="StaysOpenOnClickCheckBox" Content="StaysOpenOnClick" IsChecked="True" />
<Menu IsMainMenu="False">
<MenuItem Header="Options">
<MenuItem x:Name="InteractiveMenuItem"
Header="Interactive Item"
IsCheckable="{Binding IsChecked, ElementName=IsCheckableCheckBox}"
StaysOpenOnClick="{Binding IsChecked, ElementName=StaysOpenOnClickCheckBox}" />
</MenuItem>
</Menu>
<CheckBox x:Name="IsCheckedSyncCheckBox"
Content="IsChecked"
IsChecked="{Binding IsChecked, ElementName=InteractiveMenuItem, Mode=TwoWay}" />
</StackPanel>
Related controls and articles
Source code and how it was measured
Every behavior on this page was measured by running it on .NET 10 / Windows 11, using MenuDemoScene in this site’s screenshot tool, with menus like the demo app’s sections. Clicks and hovering were made with the real mouse, and Alt, F10, and the shortcuts were pressed as real key input; to narrow down F10, it was also sent through WPF’s input manager. The Copy item was not clicked, so that the measuring machine’s clipboard was left alone; only whether it was enabled was read.