Skip to content

Commit ea8e1aa

Browse files
authored
Keyboard accelerators (#1821)
* Keyboard accelerators draft. * Edits. * Table edit. * Edits. * Edits.
1 parent bd96400 commit ea8e1aa

File tree

7 files changed

+218
-0
lines changed

7 files changed

+218
-0
lines changed

docs/TOC.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -473,6 +473,8 @@
473473
href: user-interface/menu-bar.md
474474
- name: Display menu items
475475
href: user-interface/menuitem.md
476+
- name: Keyboard accelerators
477+
href: user-interface/keyboard-accelerators.md
476478
- name: Shadows
477479
href: user-interface/shadow.md
478480
- name: Styles

docs/user-interface/context-menu.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,12 @@ The `OnWebViewGoToRepoClicked` event handler retrieves the `CommandParameter` pr
6363
> [!WARNING]
6464
> It's not currently possible to add items to, or remove items from, the `MenuFlyout` at runtime.
6565
66+
::: moniker range=">=net-maui-8.0"
67+
68+
Keyboard accelerators can be added to context menu items, so that a context menu item can be invoked through a keyboard shortcut. For more information, see [Keyboard accelerators](~/user-interface/keyboard-accelerators.md).
69+
70+
::: moniker-end
71+
6672
### Create sub-menu items
6773

6874
Sub-menu items can be added to a context menu by adding one or more `MenuFlyoutSubItem` objects to the `MenuFlyout`:
Lines changed: 200 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,200 @@
1+
---
2+
title: "Keyboard accelerators"
3+
description: "Learn how to define keyboard accelerators on Mac Catalyst and Windows so that menu items can be invoked through keyboard shortcuts."
4+
ms.date: 10/25/2023
5+
monikerRange: ">=net-maui-8.0"
6+
---
7+
8+
# Keyboard accelerators
9+
10+
Keyboard accelerators are keyboard shortcuts that improve the usability and accessibility of your .NET Multi-platform App UI (.NET MAUI) apps on Mac Catalyst and Windows by providing an intuitive way for users to invoke common actions or commands without navigating the app UI directly.
11+
12+
A keyboard accelerator is composed of two components:
13+
14+
- Modifiers, which include Shift, Ctrl, and Alt.
15+
- Keys, which include alphanumeric keys, and special keys.
16+
17+
In .NET MAUI, keyboard accelerators are associated with commands exposed in menus, and should be specified with the menu item. Specifically, .NET MAUI keyboard accelerators can be attached to menu items in the menu bar on Mac Catalyst and Windows, and menu items in context menus on Windows. For more information about menu bars, see [Display a menu bar in a .NET MAUI desktop app](menu-bar.md). For more information about context menus, see [Display a context menu in a .NET MAUI desktop app](context-menu.md).
18+
19+
The following screenshots show menu bar items and context menu items that include keyboard accelerators:
20+
21+
:::image type="content" source="media/keyboard-accelerators/menubar.png" alt-text="Screenshot of menu bar items that include keyboard accelerators.":::
22+
:::image type="content" source="media/keyboard-accelerators/context-menu.png" alt-text="Screenshot of context menu items that include keyboard accelerators.":::
23+
24+
A keyboard accelerator is represented by the `KeyboardAccelerator` class, which represents a shortcut key for a <xref:Microsoft.Maui.Controls.MenuFlyoutItem>. The `KeyboardAccelerator` class defines the following properties:
25+
26+
- `Modifiers`, of type `KeyboardAcceleratorModifiers`, which represents the modifier value, such as Ctrl or Shift, for the keyboard shortcut.
27+
- `Key`, of type `string?`, which represents the key value for the keyboard shortcut.
28+
29+
These properties are backed by <xref:Microsoft.Maui.Controls.BindableProperty> objects, which means that they can be targets of data bindings.
30+
31+
The `KeyboardAcceleratorModifiers` enumeration defines the following members that be used as values for the `Modifiers` property:
32+
33+
- `None`, which indicates no modifier.
34+
- `Shift`, which indicates the Shift modifier on Mac Catalyst and Windows.
35+
- `Ctrl`, which indicates the Control modifier on Mac Catalyst and Windows.
36+
- `Alt`, which indicates the Option modifier on Mac Catalyst, and the Menu modifier on Windows.
37+
- `Cmd`, which indicates the Command modifier on Mac Catalyst.
38+
- `Windows`, which indicates the Windows modifier on Windows.
39+
40+
> [!IMPORTANT]
41+
> Keyboard accelerators can be attached to <xref:Microsoft.Maui.Controls.MenuFlyoutItem> objects in a <xref:Microsoft.Maui.Controls.MenuBarItem> on Mac Catalyst and Windows, and in a <xref:Microsoft.Maui.Controls.MenuFlyout> on Windows.
42+
43+
<!-- Mac Catalyst support for keyboard accelerators in context menu items is pending. -->
44+
45+
The following table outlines the keyboard accelerator formats .NET MAUI supports:
46+
47+
| Platform | Single key | Multi-key |
48+
| -------- | ---------- | --------- |
49+
| Mac Catalyst | Keyboard accelerators without a modifier, with a single key. For example, using the F1 key to invoke the action associated with a menu item. | Keyboard accelerators with one or more modifiers, with a single key. For example, using CMD+SHIFT+S or CMD+S to invoke the action associated with a menu item. |
50+
| Windows | Keyboard accelerators with and without a modifier, with a single key. For example, using the F1 key to invoke the action associated with a menu item. | Keyboard accelerators with one or more modifiers, with a single key. For example, using CTRL+SHIFT+F or CTRL+F to invoke the action associated with a menu item. |
51+
52+
## Create a keyboard accelerator
53+
54+
A `KeyboardAccelerator` can be attached to a <xref:Microsoft.Maui.Controls.MenuFlyoutItem> by adding it to its `KeyboardAccelerators` collection:
55+
56+
<!-- TODO: Why is KeyboardAccelerators a collection? Multiple allowed but only first executed on MacCat, but both executed on Win -->
57+
58+
```xaml
59+
<MenuFlyoutItem Text="Cut"
60+
Clicked="OnCutMenuFlyoutItemClicked">
61+
<MenuFlyoutItem.KeyboardAccelerators>
62+
<KeyboardAccelerator Modifiers="Ctrl"
63+
Key="X" />
64+
</MenuFlyoutItem.KeyboardAccelerators>
65+
</MenuFlyoutItem>
66+
```
67+
68+
Keyboard accelerators can also be specified in code:
69+
70+
```csharp
71+
cutMenuFlyoutItem.KeyboardAccelerators.Add(new KeyboardAccelerator
72+
{
73+
Modifiers = KeyboardAcceleratorModifiers.Ctrl,
74+
Key = "X"
75+
});
76+
```
77+
78+
When a keyboard accelerator modifier and key is pressed, the action associated with the <xref:Microsoft.Maui.Controls.MenuFlyoutItem> is invoked.
79+
80+
> [!IMPORTANT]
81+
> While multiple `KeyboardAccelerator` objects can be added to the `MenuFlyoutItem.KeyboardAccelerators` collection, only the first `KeyboardAccelerator` in the collection will have its shortcut displayed on the <xref:Microsoft.Maui.Controls.MenuFlyoutItem>. In addition, on Mac Catalyst, only the keyboard shortcut for the first `KeyboardAccelerator` in the collection will cause the action associated with the <xref:Microsoft.Maui.Controls.MenuFlyoutItem> to be invoked. However, on Windows, the keyboard shortcuts for all of the `KeyboardAccelerator` objects in the `MenuFlyoutItem.KeyboardAccelerators` collection will cause the <xref:Microsoft.Maui.Controls.MenuFlyoutItem> action to be invoked.
82+
83+
### Specify multiple modifiers
84+
85+
Multiple modifiers can be specified on a `KeyboardAccelerator` on both platforms:
86+
87+
```xaml
88+
<MenuFlyoutItem Text="Refresh"
89+
Command="{Binding RefreshCommand}">
90+
<MenuFlyoutItem.KeyboardAccelerators>
91+
<KeyboardAccelerator Modifiers="Shift,Ctrl"
92+
Key="R" />
93+
</MenuFlyoutItem.KeyboardAccelerators>
94+
</MenuFlyoutItem>
95+
```
96+
97+
The equivalent C# code is:
98+
99+
```csharp
100+
refreshMenuFlyoutItem.KeyboardAccelerators.Add(new KeyboardAccelerator
101+
{
102+
Modifiers = KeyboardAcceleratorModifiers.Shift | KeyboardAcceleratorModifiers.Ctrl,
103+
Key = "R"
104+
});
105+
```
106+
107+
## Specify keyboard accelerators per platform
108+
109+
Different keyboard accelerator modifiers and keys can be specified per platform in XAML with the [`OnPlatform`](xref:Microsoft.Maui.Controls.Xaml.OnPlatformExtension) markup extension:
110+
111+
```xaml
112+
<MenuFlyoutItem Text="Change Theme"
113+
Command="{Binding ChangeThemeCommand}">
114+
<MenuFlyoutItem.KeyboardAccelerators>
115+
<KeyboardAccelerator Modifiers="{OnPlatform MacCatalyst=Cmd, WinUI=Windows}"
116+
Key="{OnPlatform MacCatalyst=T, WinUI=C}" />
117+
</MenuFlyoutItem.KeyboardAccelerators>
118+
</MenuFlyoutItem>
119+
```
120+
121+
The equivalent C# code is:
122+
123+
```csharp
124+
KeyboardAcceleratorModifiers modifier = KeyboardAcceleratorModifiers.None;
125+
string key = string.Empty;
126+
127+
if (DeviceInfo.Current.Platform == DevicePlatform.MacCatalyst)
128+
{
129+
modifier = KeyboardAcceleratorModifiers.Cmd;
130+
key = "T";
131+
}
132+
else if (DeviceInfo.Current.Platform == DevicePlatform.WinUI)
133+
{
134+
modifier = KeyboardAcceleratorModifiers.Windows;
135+
key = "C";
136+
}
137+
138+
myMenuFlyoutItem.KeyboardAccelerators.Add(new KeyboardAccelerator
139+
{
140+
Modifiers = modifier,
141+
Key = key
142+
});
143+
```
144+
145+
## Use special keys in a keyboard accelerator
146+
147+
On Windows, special keys can be specified via a string constant or with an integer. For a list of constants and integers, see the table in <xref:Windows.System.VirtualKey>.
148+
149+
> [!NOTE]
150+
> On Windows, single key accelerators (all alphanumeric and punctuation keys, Delete, F2, Spacebar, Esc, Multimedia Key) and multi-key accelerators (Ctrl+Shift+M) are supported. However, Gamepad virtual keys aren't supported.
151+
152+
On Mac Catalyst, special keys can be specified via a string constant. For a list of constants that represent the text input strings that correspond to special keys, see [Input strings for special keys](https://developer.apple.com/documentation/uikit/uikeycommand/input_strings_for_special_keys?language=objc) on developer.apple.com.
153+
154+
The following XAML shows an example of defining a keyboard accelerator that uses a special key:
155+
156+
```xaml
157+
<MenuFlyoutItem Text="Help"
158+
Command="{Binding HelpCommand}">
159+
<MenuFlyoutItem.KeyboardAccelerators>
160+
<!-- Alternatively, 112 can be used to specify F1 on Windows -->
161+
<KeyboardAccelerator Modifiers="None"
162+
Key="{OnPlatform MacCatalyst=UIKeyInputF1, WinUI=F1}" />
163+
</MenuFlyoutItem.KeyboardAccelerators>
164+
</MenuFlyoutItem>
165+
```
166+
167+
In this example the keyboard accelerator is the F1 key, which is specified via a constant on both platforms. On Windows, it could also be specified by the integer 112.
168+
169+
## Localize a keyboard acclerator
170+
171+
Keyboard accelerator keys can be localized via a .NET resource file. The localized key can then be retrieved by using the `x:Static` markup extension:
172+
173+
```xaml
174+
<MenuFlyoutItem Text="Cut"
175+
Clicked="OnCutMenuFlyoutItemClicked">
176+
<MenuFlyoutItem.KeyboardAccelerators>
177+
<KeyboardAccelerator Modifiers="Ctrl"
178+
Key="{x:Static local:AppResources.CutAcceleratorKey}" />
179+
</MenuFlyoutItem.KeyboardAccelerators>
180+
</MenuFlyoutItem>
181+
```
182+
183+
For more information, see [Localization](~/fundamentals/localization.md).
184+
185+
## Disable a keyboard accelerator
186+
187+
When a <xref:Microsoft.Maui.Controls.MenuFlyoutItem> is disabled, the associated keyboard accelerator is also disabled:
188+
189+
```xaml
190+
<MenuFlyoutItem Text="Cut"
191+
Clicked="OnCutMenuFlyoutItemClicked"
192+
IsEnabled="false">
193+
<MenuFlyoutItem.KeyboardAccelerators>
194+
<KeyboardAccelerator Modifiers="Ctrl"
195+
Key="X" />
196+
</MenuFlyoutItem.KeyboardAccelerators>
197+
</MenuFlyoutItem>
198+
```
199+
200+
In this example, because the `IsEnabled` property of the <xref:Microsoft.Maui.Controls.MenuFlyoutItem> is set to `false`, the associated CTRL+X keyboard accelerator can't be invoked.
18.3 KB
Loading
20.6 KB
Loading

docs/user-interface/menu-bar.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,17 @@ This example defines three top-level menus. Each top-level menu has menu items,
7070

7171
:::image type="content" source="media/menubar/menubar-net7.png" alt-text="Screenshot of menu bar in .NET 7.":::
7272

73+
> [!NOTE]
74+
> On Mac Catalyst, menu items are added to the system menu bar.
75+
7376
In this example, each `MenuFlyoutItem` defines a menu item that executes an `ICommand` when selected.
7477

78+
::: moniker range=">=net-maui-8.0"
79+
80+
Keyboard accelerators can be added to menu items in a menu bar, so that a menu item can be invoked through a keyboard shortcut. For more information, see [Keyboard accelerators](~/user-interface/keyboard-accelerators.md).
81+
82+
::: moniker-end
83+
7584
## Display icons on menu items
7685

7786
`MenuFlyoutItem` and `MenuFlyoutSubItem` inherit the `IconImageSource` property from <xref:Microsoft.Maui.Controls.MenuItem>, which enables a small icon to be displayed next to the text for a menu item. This icon can either be an image, or a font icon.

docs/whats-new/dotnet-8.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ For information about what's new in .NET 8, see [What's new in .NET 8](/dotnet/c
4141
- Several system fonts can be easily consumed in Android apps. For more information, see [Consume fonts](~/user-interface/fonts.md#consume-fonts).
4242
- Shell navigation gains a `GoToAsync` overload that enables you to pass single use navigation data, that's cleared after navigation has occurred, as a `ShellNavigationQueryParameters` object. For more information, see [Pass single use object-based navigation data](~/fundamentals/shell/navigation.md#pass-single-use-object-based-navigation-data).
4343
- Window management can be decoupled from the `App` class. For more information, see [Decouple window management from the App class](~/fundamentals/windows.md#decouple-window-management-from-the-app-class).
44+
- Menu bar items and context menu items can be invoked through keyboard shortcuts known as keyboard accelerators. For more information, see [Keyboard accelerators](~/user-interface/keyboard-accelerators.md).
4445

4546
The following types or members have been deprecated:
4647

0 commit comments

Comments
 (0)