键盘快捷键

Hero image of the Surface keyboard

快捷键(或键盘快捷键)是键盘快捷方式,通过为用户提供一种直观的方法来调用常见操作或命令而不导航应用 UI,从而提高 Windows 应用程序的可用性和可访问性。

注意

对于具有某些残疾的用户来说,键盘不可缺少(请参阅 键盘辅助功能),对于喜欢键盘的用户来说,键盘也是一种更高效的方式来与应用交互的重要工具。

有关使用键盘快捷方式导航 Windows 应用程序的 UI 的详细信息,请参阅 Access 键主题。

若要创建你自己的自定义键盘快捷方式,请参阅键盘事件主题。

概述

加速器由两种类型的键组成:修饰符和非修饰符。 修饰键包括 Shift、Menu、Control 和 Windows 键,这些键通过 VirtualKeyModifiers 公开。 非修改键包括所有 VirtualKey,如 Delete、F3、空格键、箭头键、Esc 以及所有字母数字和标点符号键。

注意

加速器通常包括函数键 F1 到 F12 或标准键与一个或多个修饰键(Ctrl、Shift)配对的某种组合。 例如,如果用户按 Ctrl+Shift+M,框架将检查修改键(Ctrl 和 Shift),并触发加速键(如果存在)。

许多 XAML 控件都有内置的键盘加速键。 例如,ListView 支持 Ctrl+A 选择列表中的所有项目,RichEditBox 支持 Ctrl+Tab 在文本框中插入 Tab。 这些内置键盘快捷键称为 控制加速器 ,仅当焦点位于元素或其子元素上时才会执行。 使用此处讨论的键盘快捷键 API 定义的加速器称为 应用加速器

键盘快捷键不适用于每个操作,但通常与菜单公开的命令相关联(并且应使用菜单项内容指定)。 加速器也可以与没有等效菜单项的操作相关联。 但是,由于用户依赖应用程序的菜单来发现和了解可用的命令集,因此应尽量轻松地发现加速器(使用标签或已建立的模式可以帮助执行此操作)。

加速键会自动重复(例如,当用户按 Ctrl+Shift 然后按住 M 时,会重复调用加速键,直到松开 M 为止)。 无法修改此行为。

Screenshot of keyboard accelerators in a menu item label.
菜单项标签中所述的键盘快捷键

何时使用键盘加速器

建议在 UI 中指定键盘快捷键,并支持所有自定义控件中的快捷键。

  • 键盘快捷键使你的应用更易于使用运动障碍的用户,包括一次只能按一个键或难以使用鼠标的用户。

    设计良好的键盘 UI 是软件辅助功能的重要方面。 它使视力障碍或具有某些运动障碍的用户能够导航应用并与其功能交互。 此类用户可能无法操作鼠标,而是依赖于各种辅助技术,例如键盘增强工具、屏幕键盘、屏幕放大器、屏幕阅读器和语音输入实用工具。 对于这些用户,全面的命令覆盖率至关重要。

  • 键盘加速器使你的应用更适用于希望通过键盘交互的电源用户。

    经验丰富的用户通常倾向于使用键盘,因为基于键盘的命令可以更快地输入,并且不需要他们从键盘中删除手。 对于这些用户,效率和一致性至关重要;仅对最常用的命令而言,全面性非常重要。

指定键盘快捷键

使用 KeyboardAccelerator API 在 Windows 应用中创建键盘加速键。 使用这些 API,无需处理多个 KeyDown 事件即可检测按下的键组合,并且可以在应用资源中本地化加速器。

建议为应用中最常见的操作设置键盘快捷键,并使用菜单项标签或工具提示记录它们。 在此示例中,我们仅为“重命名”和“复制”命令声明键盘快捷键。

<CommandBar Margin="0,200" AccessKey="M">
  <AppBarButton 
    Icon="Share" 
    Label="Share" 
    Click="OnShare" 
    AccessKey="S" />
  <AppBarButton 
    Icon="Copy" 
    Label="Copy" 
    ToolTipService.ToolTip="Copy (Ctrl+C)" 
    Click="OnCopy" 
    AccessKey="C">
    <AppBarButton.KeyboardAccelerators>
      <KeyboardAccelerator 
        Modifiers="Control" 
        Key="C" />
    </AppBarButton.KeyboardAccelerators>
  </AppBarButton>

  <AppBarButton 
    Icon="Delete" 
    Label="Delete" 
    Click="OnDelete" 
    AccessKey="D" />
  <AppBarSeparator/>
  <AppBarButton 
    Icon="Rename" 
    Label="Rename" 
    ToolTipService.ToolTip="Rename (F2)" 
    Click="OnRename" 
    AccessKey="R">
    <AppBarButton.KeyboardAccelerators>
      <KeyboardAccelerator 
        Modifiers="None" Key="F2" />
    </AppBarButton.KeyboardAccelerators>
  </AppBarButton>

  <AppBarButton 
    Icon="SelectAll" 
    Label="Select" 
    Click="OnSelect" 
    AccessKey="A" />
  
  <CommandBar.SecondaryCommands>
    <AppBarButton 
      Icon="OpenWith" 
      Label="Sources" 
      AccessKey="S">
      <AppBarButton.Flyout>
        <MenuFlyout>
          <ToggleMenuFlyoutItem Text="OneDrive" />
          <ToggleMenuFlyoutItem Text="Contacts" />
          <ToggleMenuFlyoutItem Text="Photos"/>
          <ToggleMenuFlyoutItem Text="Videos"/>
        </MenuFlyout>
      </AppBarButton.Flyout>
    </AppBarButton>
    <AppBarToggleButton 
      Icon="Save" 
      Label="Auto Save" 
      IsChecked="True" 
      AccessKey="A"/>
  </CommandBar.SecondaryCommands>

</CommandBar>

Screenshot of a keyboard accelerator in a tooltip.
工具提示中所述的键盘加速器

UIElement 对象具有 KeyboardAccelerator 集合 KeyboardAccelerators,可在其中指定自定义 KeyboardAccelerator 对象并定义键盘快捷键的击键:

注意

支持单键(A、Delete、F2、空格键、Esc、多媒体键)加速器和多键快捷键(Ctrl+Shift+M)。 但是,不支持 Gamepad 虚拟密钥。

范围加速器

某些加速器仅在特定范围内工作,而另一些加速器则适用于应用范围。

例如,Microsoft Outlook 包含以下加速器:

  • Ctrl+B、Ctrl+I 和 ESC 仅适用于发送电子邮件窗体的范围
  • Ctrl+1 和 Ctrl+2 工作应用范围

上下文菜单

上下文菜单操作仅影响特定区域或元素,例如文本编辑器中的选定字符或播放列表中的歌曲。 因此,建议将上下文菜单项的键盘快捷键范围设置为上下文菜单的父菜单。

使用 ScopeOwner 属性指定键盘加速器的范围。 此代码演示如何在具有作用域键盘加速器的 ListView 上实现上下文菜单:

<ListView x:Name="MyList">
  <ListView.ContextFlyout>
    <MenuFlyout>
      <MenuFlyoutItem Text="Share" Icon="Share"/>
      <MenuFlyoutItem Text="Copy" Icon="Copy">
        <MenuFlyoutItem.KeyboardAccelerators>
          <KeyboardAccelerator 
            Modifiers="Control" 
            Key="C" 
            ScopeOwner="{x:Bind MyList }" />
        </MenuFlyoutItem.KeyboardAccelerators>
      </MenuFlyoutItem>
      
      <MenuFlyoutItem Text="Delete" Icon="Delete" />
      <MenuFlyoutSeparator />
      
      <MenuFlyoutItem Text="Rename">
        <MenuFlyoutItem.KeyboardAccelerators>
          <KeyboardAccelerator 
            Modifiers="None" 
            Key="F2" 
            ScopeOwner="{x:Bind MyList}" />
        </MenuFlyoutItem.KeyboardAccelerators>
      </MenuFlyoutItem>
      
      <MenuFlyoutItem Text="Select" />
    </MenuFlyout>
    
  </ListView.ContextFlyout>
    
  <ListViewItem>Track 1</ListViewItem>
  <ListViewItem>Alternative Track 1</ListViewItem>

</ListView>

MenuFlyoutItem.KeyboardAccelerators 元素的 ScopeOwner 属性将加速键标记为作用域而不是全局(默认值为 null 或全局)。 有关更多详细信息,请参阅本主题后面的“ 解析加速器 ”部分。

调用键盘加速器

KeyboardAccelerator 对象使用 UI 自动化 (UIA) 控件模式在调用加速器时执行操作。

UIA [控件模式] 公开了常见的控件功能。 例如,Button 控件可实现 Invoke 控件模式,以支持 Click 事件(通常,通过单击、双击或按 Enter、预定义的键盘快捷方式或其他击键组合来调用控件)。 当键盘加速器用于调用控件时,XAML 框架将查找控件是否实现 Invoke 控件模式,如果是,则激活它(无需侦听 KeyboardAcceleratorInvoked 事件)。

在以下示例中,Control+S 会触发 Click 事件,因为该按钮实现调用模式。

<Button Content="Save" Click="OnSave">
  <Button.KeyboardAccelerators>
    <KeyboardAccelerator Key="S" Modifiers="Control" />
  </Button.KeyboardAccelerators>
</Button>

如果元素实现多个控件模式,则只能通过加速器激活一个控件模式。 控件模式的优先级如下:

  1. 调用 (按钮)
  2. 切换(复选框)
  3. 选择(ListView)
  4. 展开/折叠 (组合框)

如果未识别任何匹配项,则加速器无效,并且提供了调试消息(“找不到此组件的自动化模式。在调用事件中实现所有所需行为。在事件处理程序中将 Handled 设置为 true 将禁止显示此消息。“)

自定义键盘快捷键行为

执行加速键时会触发 KeyboardAccelerator 对象的 Invoked 事件KeyboardAcceleratorInvokedEventArgs 事件对象包含以下属性:

  • Handled(布尔值):将其设置为 true 可以阻止事件触发控件模式并停止加速键事件浮升。 默认值为 false。
  • Element (DependencyObject):与加速键关联的对象。
  • KeyboardAccelerator:用于引发 Invoked 事件的键盘加速键。

在此,我们将演示如何为 ListView 中的项定义键盘加速键集合,以及如何处理每个加速键的 Invoked 事件。

<ListView x:Name="MyListView">
  <ListView.KeyboardAccelerators>
    <KeyboardAccelerator Key="A" Modifiers="Control,Shift" Invoked="SelectAllInvoked" />
    <KeyboardAccelerator Key="F5" Invoked="RefreshInvoked"  />
  </ListView.KeyboardAccelerators>
</ListView>
void SelectAllInvoked(KeyboardAccelerator sender, KeyboardAcceleratorInvokedEventArgs args)
{
  MyListView.SelectAll();
  args.Handled = true;
}

void RefreshInvoked(KeyboardAccelerator sender, KeyboardAcceleratorInvokedEventArgs args)
{
  MyListView.SelectionMode = ListViewSelectionMode.None;
  MyListView.SelectionMode = ListViewSelectionMode.Multiple;
  args.Handled = true;
}

替代默认键盘行为

某些控件在获得焦点时,支持使用内置键盘加速键来替代任何应用定义加速键。 例如,当 TextBox 获得焦点时,Ctrl+C 加速键仅复制当前选定的文本(忽略应用定义加速键并且不执行其他功能)。

虽然我们不建议替代默认控件行为(因为用户熟悉并且会预期此行为),但你可以替代控件的内置键盘加速键。 以下示例演示如何通过 PreviewKeyDown 事件处理程序替代 TextBox 的 Ctrl+C 键盘加速键:

 private void TextBlock_PreviewKeyDown(object sender, KeyRoutedEventArgs e)
 {
    var ctrlState = CoreWindow.GetForCurrentThread().GetKeyState(Windows.System.VirtualKey.Control);
    var isCtrlDown = ctrlState == CoreVirtualKeyStates.Down || ctrlState 
        ==  (CoreVirtualKeyStates.Down | CoreVirtualKeyStates.Locked);
    if (isCtrlDown && e.Key == Windows.System.VirtualKey.C)
    {
        // Your custom keyboard accelerator behavior.
        
        e.Handled = true;
    }
 }

禁用键盘快捷键

如果控件已禁用,则关联的加速器也会被禁用。 在以下示例中,由于 ListView 的 IsEnabled 属性设置为 false,因此无法调用关联的 Control+A 加速器。

<ListView >
  <ListView.KeyboardAccelerators>
    <KeyboardAccelerator Key="A"
      Modifiers="Control"
      Invoked="CustomListViewSelecAllInvoked" />
  </ListView.KeyboardAccelerators>
  
  <TextBox>
    <TextBox.KeyboardAccelerators>
      <KeyboardAccelerator 
        Key="A" 
        Modifiers="Control" 
        Invoked="CustomTextSelecAllInvoked" 
        IsEnabled="False" />
    </TextBox.KeyboardAccelerators>
  </TextBox>

<ListView>

父控件和子控件可以共享相同的加速器。 在这种情况下,即使子控件具有焦点且其加速器处于禁用状态,也可以调用父控件。

屏幕阅读器和键盘加速器

屏幕阅读器(如讲述人)可以向用户朗读键盘快捷键组合。 默认情况下,这是每个修饰符(在 VirtualModifiers 枚举顺序中),后跟键(并用“+”符号分隔)。 可以通过 AcceleratorKey AutomationProperties 附加属性自定义此属性。 如果指定了多个加速器,则仅宣布第一个加速器。

在此示例中,AutomationProperty.AcceleratorKey 返回字符串“Control+Shift+A”:

<ListView x:Name="MyListView">
  <ListView.KeyboardAccelerators>

    <KeyboardAccelerator 
      Key="A" 
      Modifiers="Control,Shift" 
      Invoked="CustomSelectAllInvoked" />
      
    <KeyboardAccelerator 
      Key="F5" 
      Modifiers="None" 
      Invoked="RefreshInvoked" />

  </ListView.KeyboardAccelerators>

</ListView>   

注意

设置 AutomationProperties.AcceleratorKey 不启用键盘功能,它仅向 UIA 框架指示使用哪些键。

常见键盘加速器

建议在 Windows 应用程序中使键盘加速键保持一致。

用户必须记住键盘加速键并且期望获得相同(或类似)的结果,但这或许并不总能实现,因为各个应用的功能不同。

编辑 通用键盘加速器
开始编辑模式 Ctrl + E
选择焦点控件或窗口中的所有项 Ctrl+A
搜索和替换 Ctrl + H
撤消 Ctrl+Z
重做 Ctrl+Y
删除所选内容并将其复制到剪贴板 Ctrl + X
将所选内容复制到剪贴板 Ctrl + C、Ctrl + 插入
粘贴剪贴板的内容 Ctrl + V、Shift + Insert
粘贴剪贴板的内容(包含选项) Ctrl + Alt + V
重命名项 F2
添加新项 Ctrl+N
添加新的辅助项 Ctrl + Shift + N
删除所选项目(撤消) Del、Ctrl+D
删除所选项目(未撤消) Shift + Del
粗体 Ctrl + B
下划线 Ctrl + U
斜体 Ctrl+I
导航
在焦点控件或窗口中查找内容 Ctrl+F
转到下一个搜索结果 F3
其他操作
添加收藏夹 Ctrl + D
刷新 F5 或 Ctrl + R
放大 Ctrl + +
缩小 Ctrl + -
缩放到默认视图 Ctrl + 0
保存 Ctrl+S
关闭 Ctrl + W
打印 Ctrl+P

请注意,某些组合对 Windows 的本地化版本无效。 例如,在西班牙语版本的 Windows 中,Ctrl+N 用于粗体而不是 Ctrl+B。 如果应用已本地化,我们建议提供本地化的键盘加速器。

键盘快捷键的可用性功能

工具提示

由于 Windows 应用程序的 UI 中一般并不直接说明键盘加速键,因此,你可以通过工具提示提高可发现性,当用户将焦点移动到某个控件、按住某个控件或将鼠标指针悬停在某个控件上时,会自动显示工具提示。 工具提示可以识别控件是否具有关联的键盘快捷键,如果是这样,快捷键组合是什么。

Windows 10 版本 1803(2018 年 4 月更新)及更高版本

默认情况下,当声明键盘加速键时,所有控件(MenuFlyoutItemToggleMenuFlyoutItem 除外)都会在工具提示中显示相应的组合键。

注意

如果某个控件定义了多个加速键,工具提示中只显示第一个加速键。

Screenshot of a Save button with a tool tip above it that indicates support for the Ctrl+S accelerator.
工具提示中的加速器键组合

对于 ButtonAppBarButtonAppBarToggleButton 对象,键盘加速键将追加到控件的默认工具提示中。 对于 MenuFlyoutItemToggleMenuFlyoutItem 对象,键盘加速键与浮出控件文本一起显示。

注意

指定工具提示(见以下示例中的 Button1)会替代此行为。

<StackPanel x:Name="Container" Grid.Row="0" Background="AliceBlue">
    <Button Content="Button1" Margin="20"
            Click="OnSave" 
            KeyboardAcceleratorPlacementMode="Auto" 
            ToolTipService.ToolTip="Tooltip">
        <Button.KeyboardAccelerators>
            <KeyboardAccelerator  Key="A" Modifiers="Windows"/>
        </Button.KeyboardAccelerators>
    </Button>
    <Button Content="Button2"  Margin="20"
            Click="OnSave" 
            KeyboardAcceleratorPlacementMode="Auto">
        <Button.KeyboardAccelerators>
            <KeyboardAccelerator  Key="B" Modifiers="Windows"/>
        </Button.KeyboardAccelerators>
    </Button>
    <Button Content="Button3"  Margin="20"
            Click="OnSave" 
            KeyboardAcceleratorPlacementMode="Auto">
        <Button.KeyboardAccelerators>
            <KeyboardAccelerator  Key="C" Modifiers="Windows"/>
        </Button.KeyboardAccelerators>
    </Button>
</StackPanel>

Screenshot of three buttons labeled Button1, Button2, and Button3 with a tool tip above Button2 that indicates support for the Windows+B accelerator.

追加到 Button 的默认工具提示的加速键组合

<AppBarButton Icon="Save" Label="Save">
    <AppBarButton.KeyboardAccelerators>
        <KeyboardAccelerator Key="S" Modifiers="Control"/>
    </AppBarButton.KeyboardAccelerators>
</AppBarButton>

Screenshot of a button with a Disk icon and a tool tip that includes the default Save text appended with the Ctrl+S accelerator in parentheses.

追加到 AppBarButton 的默认工具提示的加速键组合

<AppBarButton AccessKey="R" Icon="Refresh" Label="Refresh" IsAccessKeyScope="True">
    <AppBarButton.Flyout>
        <MenuFlyout>
            <MenuFlyoutItem AccessKey="A" Icon="Refresh" Text="Refresh A">
                <MenuFlyoutItem.KeyboardAccelerators>
                    <KeyboardAccelerator Key="R" Modifiers="Control"/>
                </MenuFlyoutItem.KeyboardAccelerators>
            </MenuFlyoutItem>
            <MenuFlyoutItem AccessKey="B" Icon="Globe" Text="Refresh B" />
            <MenuFlyoutItem AccessKey="C" Icon="Globe" Text="Refresh C" />
            <MenuFlyoutItem AccessKey="D" Icon="Globe" Text="Refresh D" />
            <ToggleMenuFlyoutItem AccessKey="E" Icon="Globe" Text="ToggleMe">
                <MenuFlyoutItem.KeyboardAccelerators>
                    <KeyboardAccelerator Key="Q" Modifiers="Control"/>
                </MenuFlyoutItem.KeyboardAccelerators>
            </ToggleMenuFlyoutItem>
        </MenuFlyout>
    </AppBarButton.Flyout>
</AppBarButton>

Screenshot of a Menu with MenuFlyoutItems that include accelerator key combos.
追加到 MenuFlyoutItem 文本的快捷键组合

使用 KeyboardAcceleratorPlacementMode 属性控制呈现行为,该属性接受两个值: 自动隐藏

<Button Content="Save" Click="OnSave" KeyboardAcceleratorPlacementMode="Auto">
    <Button.KeyboardAccelerators>
        <KeyboardAccelerator Key="S" Modifiers="Control" />
    </Button.KeyboardAccelerators>
</Button>

在某些情况下,可能需要相对于另一个元素(通常是容器对象)呈现工具提示。

在这里,我们将演示如何使用 KeyboardAcceleratorPlacementTarget 属性显示“保存”按钮的键盘快捷键组合,以及网格容器而不是按钮。

<Grid x:Name="Container" Padding="30">
  <Button Content="Save"
    Click="OnSave"
    KeyboardAcceleratorPlacementMode="Auto"
    KeyboardAcceleratorPlacementTarget="{x:Bind Container}">
    <Button.KeyboardAccelerators>
      <KeyboardAccelerator  Key="S" Modifiers="Control" />
    </Button.KeyboardAccelerators>
  </Button>
</Grid>

标签

在某些情况下,我们建议使用控件的标签来标识控件是否具有关联的键盘快捷键,如果是,那么快捷键组合是什么。

默认情况下,某些平台控件会执行此操作,特别是 MenuFlyoutItemToggleMenuFlyoutItem 对象,而 AppBarButtonAppBarToggleButton 会在命令栏溢出菜单中显示时执行此操作。

Keyboard accelerators described in a menu item label.
菜单项标签中所述的键盘快捷键

可以通过 MenuFlyoutItem、ToggleMenuFlyoutItem、AppBarButton 和 AppBarToggleButton 控件的 KeyboardAcceleratorTextOverride 属性替代标签的默认快捷键文本(对无文本使用单个空格)。

注意

如果系统无法检测到附加的键盘,则不会显示替代文本(可以通过 KeyboardPresent 属性自行检查)。

高级概念

在这里,我们回顾了键盘加速器的一些低级别方面。

输入事件优先级

输入事件在特定序列中发生,你可以根据应用的要求截获和处理这些事件。

KeyDown/KeyUp 冒泡事件

在 XAML 中,将像只有一个输入冒泡管道一样处理击键。 KeyDown/KeyUp 事件和字符输入使用此输入管道。 例如,如果元素具有焦点,并且用户按下某个键,则会在元素上引发 KeyDown 事件,后跟元素的父级,依此树向上,直到参数。句柄属性为 true。

KeyDown 事件也由某些控件用来实现内置控件加速器。 当控件具有键盘快捷键时,它将处理 KeyDown 事件,这意味着不会发生 KeyDown 事件冒泡。 例如,RichEditBox 支持使用 Ctrl+C 进行复制。 按下 Ctrl 时,将触发 KeyDown 事件并引发气泡,但当用户同时按 C 时,KeyDown 事件将标记为 Handled 且不会引发(除非 UIElement.AddHandlerhandledEventsToo 参数设置为 true)。

CharacterReceived 事件

由于在 TextBox 等文本控件的 KeyDown 事件后触发 CharacterReceived 事件,因此可以在 KeyDown 事件处理程序中取消字符输入。

PreviewKeyDown 和 PreviewKeyUp 事件

预览输入事件在任何其他事件之前触发。 如果不处理这些事件,则会触发具有焦点的元素的加速器,后跟 KeyDown 事件。 这两个事件在处理之前会冒泡。

Diagram showing the key event sequence键事件序列

事件顺序:

预览 KeyDown 事件
...
应用加速键
OnKeyDown 方法
KeyDown 事件
父项上的应用加速键
父项上的 OnKeyDown 方法
父项上的 KeyDown 事件
(浮升至根)
...
CharacterReceived 事件
PreviewKeyUp 事件
KeyUp 事件

处理加速器事件时,KeyDown 事件也会标记为已处理。 KeyUp 事件保持不变。

解析加速器

键盘快捷键事件从具有焦点到根的元素中冒泡。 如果未处理该事件,XAML 框架将查找浮泡路径之外的其他未范围应用加速器。

使用同一键组合定义两个键盘快捷键时,将调用在可视化树上找到的第一个键盘快捷键。

仅当焦点位于特定作用域内时,才会调用限定范围的键盘加速器。 例如,在包含数十个控件的网格中,仅当焦点位于 Grid(范围所有者)内时,才能为控件调用键盘快捷键。

以编程方式限定加速键的范围

UIElement.TryInvokeKeyboardAccelerator 方法调用元素的子树中的任何匹配加速器。

UIElement.OnProcessKeyboardAccelerators 方法在键盘加速器之前执行。 此方法传递一个 ProcessKeyboardAcceleratorArgs 对象,该对象包含键、修饰符和一个布尔值,该对象指示是否处理键盘加速器。 如果标记为已处理,键盘快捷键将气泡(因此,永远不会调用外部键盘快捷键)。

注意

OnProcessKeyboardAccelerators 始终触发(是否处理(类似于 OnKeyDown 事件)。 必须检查事件是否已标记为已处理。

在此示例中,我们使用 OnProcessKeyboardAccelerators 和 TryInvokeKeyboardAccelerator 将键盘加速器限定为 Page 对象:

protected override void OnProcessKeyboardAccelerators(
  ProcessKeyboardAcceleratorArgs args)
{
  if(args.Handled != true)
  {
    this.TryInvokeKeyboardAccelerator(args);
    args.Handled = true;
  }
}

本地化加速器

建议本地化所有键盘加速器。 你可以使用标准资源 (.resw) 文件和 XAML 声明中的 X:uid 属性来执行此操作。 在此示例中,Windows 运行时会自动加载资源。

Diagram of keyboard accelerator localization with the resources file使用资源文件的键盘加速器本地化

<Button x:Uid="myButton" Click="OnSave">
  <Button.KeyboardAccelerators>
    <KeyboardAccelerator x:Uid="myKeyAccelerator" Modifiers="Control"/>
  </Button.KeyboardAccelerators>
</Button>

注意

键盘快捷键作为虚拟键实现。 必须从虚拟密钥代码预定义集合中选择本地化加速器(否则,将发生 XAML 分析器错误)。

以编程方式设置加速器

下面是以编程方式定义加速器的示例:

void AddAccelerator(
  VirtualKeyModifiers keyModifiers, 
  VirtualKey key, 
  TypedEventHandler<KeyboardAccelerator, KeyboardAcceleratorInvokedEventArgs> handler )
  {
    var accelerator = 
      new KeyboardAccelerator() 
      { 
        Modifiers = keyModifiers, Key = key
      };
    accelerator.Invoked += handler;
    this.KeyboardAccelerators.Add(accelerator);
  }

注意

KeyboardAccelerator 不可共享,无法将同一 KeyboardAccelerator 添加到多个元素。

替代键盘快捷键行为

可以处理 KeyboardAccelerator.Invoked 事件以替代默认的 KeyboardAccelerator 行为。

此示例演示如何在自定义 ListView 控件中重写“全选”命令(Ctrl+A 键盘快捷键)。 我们还将 Handled 属性设置为 true 以进一步停止事件冒泡。

public class MyListView : ListView
{
  …
  protected override void OnKeyboardAcceleratorInvoked(KeyboardAcceleratorInvokedEventArgs args) 
  {
    if(args.Accelerator.Key == VirtualKey.A 
      && args.Accelerator.Modifiers == KeyboardModifiers.Control)
    {
      CustomSelectAll(TypeOfSelection.OnlyNumbers); 
      args.Handled = true;
    }
  }
  …
}

示例