diff --git a/docs/TOC.yml b/docs/TOC.yml index 1ce9c199e8..4c34009779 100644 --- a/docs/TOC.yml +++ b/docs/TOC.yml @@ -473,6 +473,8 @@ href: user-interface/menu-bar.md - name: Display menu items href: user-interface/menuitem.md + - name: Keyboard accelerators + href: user-interface/keyboard-accelerators.md - name: Shadows href: user-interface/shadow.md - name: Styles diff --git a/docs/user-interface/context-menu.md b/docs/user-interface/context-menu.md index 5669fb2d61..3ca8c2434d 100644 --- a/docs/user-interface/context-menu.md +++ b/docs/user-interface/context-menu.md @@ -63,6 +63,12 @@ The `OnWebViewGoToRepoClicked` event handler retrieves the `CommandParameter` pr > [!WARNING] > It's not currently possible to add items to, or remove items from, the `MenuFlyout` at runtime. +::: moniker range=">=net-maui-8.0" + +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). + +::: moniker-end + ### Create sub-menu items Sub-menu items can be added to a context menu by adding one or more `MenuFlyoutSubItem` objects to the `MenuFlyout`: diff --git a/docs/user-interface/keyboard-accelerators.md b/docs/user-interface/keyboard-accelerators.md new file mode 100644 index 0000000000..af91b8c884 --- /dev/null +++ b/docs/user-interface/keyboard-accelerators.md @@ -0,0 +1,200 @@ +--- +title: "Keyboard accelerators" +description: "Learn how to define keyboard accelerators on Mac Catalyst and Windows so that menu items can be invoked through keyboard shortcuts." +ms.date: 10/25/2023 +monikerRange: ">=net-maui-8.0" +--- + +# Keyboard accelerators + +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. + +A keyboard accelerator is composed of two components: + +- Modifiers, which include Shift, Ctrl, and Alt. +- Keys, which include alphanumeric keys, and special keys. + +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). + +The following screenshots show menu bar items and context menu items that include keyboard accelerators: + +:::image type="content" source="media/keyboard-accelerators/menubar.png" alt-text="Screenshot of menu bar items that include keyboard accelerators."::: +:::image type="content" source="media/keyboard-accelerators/context-menu.png" alt-text="Screenshot of context menu items that include keyboard accelerators."::: + +A keyboard accelerator is represented by the `KeyboardAccelerator` class, which represents a shortcut key for a . The `KeyboardAccelerator` class defines the following properties: + +- `Modifiers`, of type `KeyboardAcceleratorModifiers`, which represents the modifier value, such as Ctrl or Shift, for the keyboard shortcut. +- `Key`, of type `string?`, which represents the key value for the keyboard shortcut. + +These properties are backed by objects, which means that they can be targets of data bindings. + +The `KeyboardAcceleratorModifiers` enumeration defines the following members that be used as values for the `Modifiers` property: + +- `None`, which indicates no modifier. +- `Shift`, which indicates the Shift modifier on Mac Catalyst and Windows. +- `Ctrl`, which indicates the Control modifier on Mac Catalyst and Windows. +- `Alt`, which indicates the Option modifier on Mac Catalyst, and the Menu modifier on Windows. +- `Cmd`, which indicates the Command modifier on Mac Catalyst. +- `Windows`, which indicates the Windows modifier on Windows. + +> [!IMPORTANT] +> Keyboard accelerators can be attached to objects in a on Mac Catalyst and Windows, and in a on Windows. + + + +The following table outlines the keyboard accelerator formats .NET MAUI supports: + +| Platform | Single key | Multi-key | +| -------- | ---------- | --------- | +| 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. | +| 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. | + +## Create a keyboard accelerator + +A `KeyboardAccelerator` can be attached to a by adding it to its `KeyboardAccelerators` collection: + + + +```xaml + + + + + +``` + +Keyboard accelerators can also be specified in code: + +```csharp +cutMenuFlyoutItem.KeyboardAccelerators.Add(new KeyboardAccelerator +{ + Modifiers = KeyboardAcceleratorModifiers.Ctrl, + Key = "X" +}); +``` + +When a keyboard accelerator modifier and key is pressed, the action associated with the is invoked. + +> [!IMPORTANT] +> 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 . In addition, on Mac Catalyst, only the keyboard shortcut for the first `KeyboardAccelerator` in the collection will cause the action associated with the to be invoked. However, on Windows, the keyboard shortcuts for all of the `KeyboardAccelerator` objects in the `MenuFlyoutItem.KeyboardAccelerators` collection will cause the action to be invoked. + +### Specify multiple modifiers + +Multiple modifiers can be specified on a `KeyboardAccelerator` on both platforms: + +```xaml + + + + + +``` + +The equivalent C# code is: + +```csharp +refreshMenuFlyoutItem.KeyboardAccelerators.Add(new KeyboardAccelerator +{ + Modifiers = KeyboardAcceleratorModifiers.Shift | KeyboardAcceleratorModifiers.Ctrl, + Key = "R" +}); +``` + +## Specify keyboard accelerators per platform + +Different keyboard accelerator modifiers and keys can be specified per platform in XAML with the [`OnPlatform`](xref:Microsoft.Maui.Controls.Xaml.OnPlatformExtension) markup extension: + +```xaml + + + + + +``` + +The equivalent C# code is: + +```csharp +KeyboardAcceleratorModifiers modifier = KeyboardAcceleratorModifiers.None; +string key = string.Empty; + +if (DeviceInfo.Current.Platform == DevicePlatform.MacCatalyst) +{ + modifier = KeyboardAcceleratorModifiers.Cmd; + key = "T"; +} +else if (DeviceInfo.Current.Platform == DevicePlatform.WinUI) +{ + modifier = KeyboardAcceleratorModifiers.Windows; + key = "C"; +} + +myMenuFlyoutItem.KeyboardAccelerators.Add(new KeyboardAccelerator +{ + Modifiers = modifier, + Key = key +}); +``` + +## Use special keys in a keyboard accelerator + +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 . + +> [!NOTE] +> 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. + +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. + +The following XAML shows an example of defining a keyboard accelerator that uses a special key: + +```xaml + + + + + + +``` + +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. + +## Localize a keyboard acclerator + +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: + +```xaml + + + + + +``` + +For more information, see [Localization](~/fundamentals/localization.md). + +## Disable a keyboard accelerator + +When a is disabled, the associated keyboard accelerator is also disabled: + +```xaml + + + + + +``` + +In this example, because the `IsEnabled` property of the is set to `false`, the associated CTRL+X keyboard accelerator can't be invoked. diff --git a/docs/user-interface/media/keyboard-accelerators/context-menu.png b/docs/user-interface/media/keyboard-accelerators/context-menu.png new file mode 100644 index 0000000000..d7c601b4ef Binary files /dev/null and b/docs/user-interface/media/keyboard-accelerators/context-menu.png differ diff --git a/docs/user-interface/media/keyboard-accelerators/menubar.png b/docs/user-interface/media/keyboard-accelerators/menubar.png new file mode 100644 index 0000000000..dc74bb70f1 Binary files /dev/null and b/docs/user-interface/media/keyboard-accelerators/menubar.png differ diff --git a/docs/user-interface/menu-bar.md b/docs/user-interface/menu-bar.md index 6483fcdbcb..7a8986bae7 100644 --- a/docs/user-interface/menu-bar.md +++ b/docs/user-interface/menu-bar.md @@ -70,8 +70,17 @@ This example defines three top-level menus. Each top-level menu has menu items, :::image type="content" source="media/menubar/menubar-net7.png" alt-text="Screenshot of menu bar in .NET 7."::: +> [!NOTE] +> On Mac Catalyst, menu items are added to the system menu bar. + In this example, each `MenuFlyoutItem` defines a menu item that executes an `ICommand` when selected. +::: moniker range=">=net-maui-8.0" + +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). + +::: moniker-end + ## Display icons on menu items `MenuFlyoutItem` and `MenuFlyoutSubItem` inherit the `IconImageSource` property from , 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. diff --git a/docs/whats-new/dotnet-8.md b/docs/whats-new/dotnet-8.md index 1b4b20aa4c..2ddfff0591 100644 --- a/docs/whats-new/dotnet-8.md +++ b/docs/whats-new/dotnet-8.md @@ -41,6 +41,7 @@ For information about what's new in .NET 8, see [What's new in .NET 8](/dotnet/c - Several system fonts can be easily consumed in Android apps. For more information, see [Consume fonts](~/user-interface/fonts.md#consume-fonts). - 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). - 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). +- 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). The following types or members have been deprecated: