语言: HTML | XAML

响应键盘交互 (XAML)

在使用键盘和类事件处理程序中的应用响应来自硬件或触摸键盘的击键操作。

要点  

某些 Windows 运行时控件在内部处理输入事件。在这些情况下,输入事件好像没有发生,因为你的事件侦听器没有调用相关联的处理程序。通常,类处理程序将处理这些键的子集以提供对基本键盘辅助功能的内置支持。例如,Button 类将替代空格键和 Enter 键的 OnKeyDown 事件(OnPointerPressed 也是如此),并将其路由到控件的 Click 事件。当控件类处理按键时,不会引发 KeyDownKeyUp 事件。

这提供了与调用按钮等效的内置键盘,效果与使用手指点击或使用鼠标单击相似。空格键或 Enter 键之外的键仍会引发 KeyDownKeyUp 事件。请参阅事件和路由事件概述,以获得关于如何基于类处理事件的详细信息(具体而言,控件中的输入事件处理程序)。

提示  本主题中的信息特定于使用 C++、C# 或 Visual Basic 开发应用。

请参阅响应键盘交互 (HTML) 以了解使用 JavaScript 的应用。

先决条件:  阅读这些主题来熟悉此处讨论的技术。

使用 C# 或 Visual Basic 创建你的第一个 Windows 应用商店应用

使用 C++ 创建你的第一个 Windows 应用商店应用

使用 C# 或 Visual Basic 的 Windows 应用商店应用的路线图

使用 C++ 的 Windows 应用商店应用的路线图

借助事件和路由事件概述了解事件

应用功能详细信息:  更深入地了解此功能以作为应用功能大全系列的一部分

用户交互详细信息 (XAML)

用户交互自定义详细信息 (XAML)

用户体验指南:  

平台控件库(HTMLXAML)提供完整用户交互体验,包括标准交互、动态显示的物理效果和视觉反馈。 如果你不需要自定义的交互支持,请使用这些内置控件。

如果平台控件不够,那么以下用户交互指南可以帮助你提供一种在各种输入模式上保持一致的令人信服的沉浸式交互体验。这些指南主要侧重于触摸输入,但也有与触摸板、鼠标、键盘和触笔输入相关的一些内容。

示例:  应用示例中查看正在使用的功能。

输入示例

输入:设备功能示例

输入:触摸键盘示例

响应屏幕键盘外观的示例

概述

键盘输入是应用的所有用户交互体验的一个重要部分。对于残障人士,或者只是认为键盘是与应用交互的最有效方法的用户而言,键盘非常重要。例如,用户应可以使用 Tab 和箭头键导航应用,使用空格键和 Enter 键激活 UI 元素,并使用键盘快捷方式访问命令。

具有良好设计的键盘 UI 是软件辅助功能的一个重要方面。它使具有视力缺陷或行动有障碍的用户能够在应用中导航并与应用的功能进行交互。这些用户可能无法操作鼠标,而不是依靠各种辅助性技术,如键盘增强工具,屏幕上的键盘,屏幕放大器,屏幕阅读器,语音输入实用工具。

最常见的键盘类型是在物理上连接到设备的外部硬件键盘。除了硬件键盘之外,Windows 8 还提供两个软件键盘:

  • 注意  窗口:

    屏幕键盘是一种可视软件键盘,你可以借助触摸、鼠标、笔/触笔或其他指针设备(不需要触摸屏)来使用屏幕键盘代替物理键盘键入和输入数据。屏幕键盘是针对没有物理键盘的系统提供的,或者是为行动有障碍而无法使用传统物理输入设备的用户提供使用。屏幕键盘模拟硬件键盘的大部分功能(如果不是全部功能)。

    屏幕键盘

  • 注意  窗口:

    触摸键盘是一种借助触摸屏输入来输入文本的可视软件键盘。触摸键盘不可以代替屏幕键盘,因为它仅用于文本输入(它不模拟硬件键盘),并且仅在文本字段或其他可编辑的文本控件获得焦点时显示。
    注意  屏幕键盘优先级高于触摸键盘,如果提供了屏幕键盘,将不会显示触摸键盘。

    以下是触摸键盘的示例。第一个图像是默认布局,第二个图像是缩略图布局(可能不适用于所有语言)。

    默认布局中的触摸键盘

    缩略图布局中的触摸键盘

键盘事件

以下键盘事件可用于硬件和触摸键盘。

事件描述
KeyDown 按下某个键时发生。
KeyUp 释放某个键时发生。

 

键盘事件和焦点

仅当 UI 中的控件具有输入焦点时才会生成键盘事件。当用户直接单击或点击布局中的一个控件时该控件获得焦点,或者使用 Tab 键进入内容区域内的 Tab 序列。

也可以调用控件的 Focus 方法来强制使用焦点。当实现快捷键时需要此操作,因为 UI 加载时默认情况下不设置键盘焦点。有关详细信息,请参阅本主题后面部分的快捷键示例

若要使某个控件接收输入焦点,则必须启用该控件,该控件必须可见并且 IsTabStopHitTestVisible 的属性值必须为 true。这是大多数控件的默认状态。当某个控件具有输入焦点时,该控件可能引发并响应键盘输入事件,如本主题后面部分所述。你也可以通过处理 GotFocusLostFocus 事件来响应接收或丢失焦点的控件。

默认情况下,控件的 Tab 序列顺序为它们在 XAML 中的顺序。但是,可以使用 TabIndex 属性修改此顺序。有关详细信息,请参阅实现键盘辅助功能

键盘事件处理程序

输入事件处理程序实现提供以下信息的委派:

  • 事件的发送者。发送者报告附加事件处理程序的对象。
  • 事件数据。对于键盘事件,该数据将是 KeyRoutedEventArgs 的一个实例。处理程序的委派为 KeyEventHandler。对于大多数处理程序方案而言,KeyRoutedEventArgs 的最为相关的属性是 Key,并且可能为 KeyStatus
  • OriginalSource。由于键盘事件是路由的事件,因此事件数据提供 OriginalSource。如果有意允许事件通过对象树向上浮生,则 OriginalSource 有时是所涉及的对象而不是发送者。但是,这取决于你的设计。有关如何使用 OriginalSource 而不是发送者的详细信息,请参阅本主题中的“键盘路由事件”部分或事件和路由事件概述

附加键盘事件处理程序

可以为将事件作为成员包含的任何对象附加键盘事件处理程序功能。这包括任何 UIElement 派生类。以下 XAML 示例显示了如何为 GridKeyUp 事件附加处理程序。



<Grid KeyUp="Grid_KeyUp">
  ...
</Grid>


也可以在代码中附加事件处理程序。有关详细信息,请参阅事件和路由事件概述

定义键盘事件处理程序

以下示例显示了在上一示例中附加的 KeyUp 事件处理程序的不完整事件处理程序定义。


void MyProject::MainPage::Grid_KeyUp(
  Platform::Object^ sender,
  Windows::UI::Xaml::Input::KeyRoutedEventArgs^ e)
{//handling code here}

使用 KeyRoutedEventArgs

所有键盘事件对事件数据均使用 KeyRoutedEventArgsKeyRoutedEventArgs 包含以下属性:

如果按下某个键,则引发 KeyDown 事件。同样,如果释放某个键,则引发 KeyUp。通常会侦听这些事件以处理特定键值。若要确定按下或释放了哪个键,请检查事件数据中的 Key 值。Key 返回 VirtualKey 值。VirtualKey 枚举包括所有受支持的键。

修改键

注意  窗口:

修改键是用户通常与其他键组合而按下的键,如 Ctrl 或 Shift。你的应用可以使用这些组合作为键盘快捷方式来调用应用命令。

使用 KeyDownKeyUp 事件处理程序中的代码检测快捷组合键。然后,你可以跟踪感兴趣的修改键的按下状态。当非修改键发生键盘事件时,可以同时检查修改键是否处于按下状态。

注意  Alt 键由 VirtualKey.Menu 值表示。

快捷键示例

注意  窗口:

以下示例演示如何实现快捷键。在此示例中,用户可以使用 Play、Pause 和 Stop 按钮或 Ctrl+P、Ctrl+A 和 Ctrl+S 键盘快捷键来控制媒体播放。按钮 XAML 通过使用工具提示和按钮标签中的 AutomationProperties 属性来显示快捷键。此自述文档对于增加应用的有用性和辅助功能非常重要。有关详细信息,请参阅实现键盘辅助功能

另请注意,加载页面时页面将输入焦点设置为其自身。如果没有此步骤,则不会有控件获得初始输入焦点,并且在用户手动设置输入焦点之前,应用不会引发输入事件(例如,通过 Tab 浏览或单击某个控件)。


<Grid KeyDown="Grid_KeyDown">

  <Grid.RowDefinitions>
    <RowDefinition Height="Auto" />
    <RowDefinition Height="Auto" />
  </Grid.RowDefinitions>

  <MediaElement x:Name="DemoMovie" Source="xbox.wmv" 
    Width="500" Height="500" Margin="20" HorizontalAlignment="Center" />

  <StackPanel Grid.Row="1" Margin="10"
    Orientation="Horizontal" HorizontalAlignment="Center">

    <Button x:Name="PlayButton" Click="MediaButton_Click"
      ToolTipService.ToolTip="Shortcut key: Ctrl+P"
      AutomationProperties.AcceleratorKey="Control P">
      <TextBlock>Play</TextBlock>
    </Button>

    <Button x:Name="PauseButton" Click="MediaButton_Click"
      ToolTipService.ToolTip="Shortcut key: Ctrl+A" 
      AutomationProperties.AcceleratorKey="Control A">
      <TextBlock>Pause</TextBlock>
    </Button>

    <Button x:Name="StopButton" Click="MediaButton_Click"
      ToolTipService.ToolTip="Shortcut key: Ctrl+S" 
      AutomationProperties.AcceleratorKey="Control S">
      <TextBlock>Stop</TextBlock>
    </Button>

  </StackPanel>

</Grid>



//showing implementations but not header definitions
void MainPage::OnNavigatedTo(NavigationEventArgs^ e)
{
    (void) e;    // Unused parameter
    this->Loaded+=ref new RoutedEventHandler(this,&MainPage::ProgrammaticFocus);
}
void MainPage::ProgrammaticFocus(Object^ sender, RoutedEventArgs^ e) {
    this->Focus(Windows::UI::Xaml::FocusState::Programmatic);
}

void KeyboardSupport::MainPage::MediaButton_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
{
    FrameworkElement^ fe = safe_cast<FrameworkElement^>(sender);
    if (fe->Name == "PlayButton") {DemoMovie->Play();}
    if (fe->Name == "PauseButton") {DemoMovie->Pause();}
    if (fe->Name == "StopButton") {DemoMovie->Stop();}
}


void KeyboardSupport::MainPage::Grid_KeyDown(Platform::Object^ sender, Windows::UI::Xaml::Input::KeyRoutedEventArgs^ e)
{
    if (e->Key == VirtualKey::Control) isCtrlKeyPressed = true;
}


void KeyboardSupport::MainPage::Grid_KeyUp(Platform::Object^ sender, Windows::UI::Xaml::Input::KeyRoutedEventArgs^ e)
{
    if (e->Key == VirtualKey::Control) isCtrlKeyPressed = true;
    else if (isCtrlKeyPressed) {
        if (e->Key==VirtualKey::P) {
            DemoMovie->Play();
        }
        if (e->Key==VirtualKey::A) {DemoMovie->Pause();}
        if (e->Key==VirtualKey::S) {DemoMovie->Stop();}
    }
}


注意  在 XAML 中设置 AutomationProperties.AcceleratorKeyAutomationProperties.AccessKey 会提供字符串信息,这可记录用于调用该特定操作的快捷键。该信息由 Microsoft UI 自动化客户端(如讲述人)捕获,且通常直接提供给用户。设置 AutomationProperties.AcceleratorKeyAutomationProperties.AccessKey 不会自行执行任何操作。你将仍需要附加 KeyDownKeyUp 事件的处理程序,以便在你的应用中真正实现键盘快捷键行为。此外,不会自动为访问键提供带下划线的文本效果。如果你希望在 UI 中显示带下划线的文本,则必须明确对助记键中特定键的文本标注下划线,作为嵌入式 Underline 格式。

键盘路由事件

有些事件为路由事件,这些事件包括 KeyDownKeyUp。路由事件使用浮升路由策略。浮升路由策略意味着某个事件从子对象开始,然后向上路由到对象树中的连续父对象。这样便提供了处理相同事件以及与相同数据数据交互的另一个机会。

请考虑以下 XAML 示例,该示例处理一个 Canvas 和两个 Button 对象的 KeyUp 事件。这种情况下,如果在任一 Button 对象拥有焦点的同时释放键,则会引发 KeyUp 事件。然后,该事件向上浮升到父 Canvas


<StackPanel KeyUp="StackPanel_KeyUp">
  <Button Name="ButtonA" Content="Button A"/>
  <Button Name="ButtonB" Content="Button B"/>
  <TextBlock Name="statusTextBlock"/>
</StackPanel>


以下示例显示如何为前面示例中对应的 XAML 内容实现 KeyUp 事件处理程序。


void StackPanel_KeyUp(object sender, KeyRoutedEventArgs e)
{
    statusTextBlock.Text = String.Format(
        "The key {0} was pressed while focus was on {1}",
        e.Key.ToString(), (e.OriginalSource as FrameworkElement).Name);
}


请注意前面的处理程序中的 OriginalSource 属性的用法。此处,OriginalSource 报告引发此事件的对象。该对象不可能是 StackPanel,因为 StackPanel 不是控件,因此无法拥有焦点。只有 StackPanel 中的两个按钮之一可能引发此事件,但是是哪一个按钮呢?如果在父对象上处理此事件,则会使用 OriginalSource 来辨别实际的事件源对象。

事件数据中的 Handled 属性

根据你的事件处理策略,你可能希望只有一个事件处理程序对浮升事件进行响应。例如,如果已将特定的 KeyUp 处理程序附加到其中一个 Button 控件,则这是处理该事件的第一次机会。这种情况下,你可能不希望父面板也处理该事件。对于此方案,可以使用事件数据中的 Handled 属性。

路由事件数据类中的 Handled 属性用于报告之前在事件路由上注册的另一个处理程序已进行操作。这会影响路由事件系统的行为。在事件处理程序中将 Handled 设置为 true 时,该事件停止路由,但不会发送到连续的父元素。

AddHandler 和 already-handled 键盘事件

可以使用特殊技术来附加处理程序,该技术对已标记为已处理的事件进行操作。此技术使用 AddHandler 方法来注册处理程序,而不是使用 XAML 属性或特定语言的添加处理程序语法,如在 C# 中的“+=”。此技术的局限性通常是 AddHandler API 带有一个类型为 RoutedEvent 的参数,该参数标识有问题的路由事件。并非所有路由事件都提供 RoutedEvent 标识符,因此此注意事项会影响在 Handled 情况下仍然可以处理哪些路由事件。KeyDownKeyUp 事件在 UIElement 上拥有路由事件标识符(KeyDownEventKeyUpEvent)。但是,其他事件(如 TextBox.TextChanged)没有路由事件标识符,因此不能使用 AddHandler 技术。

命令处理

少量 UI 元素提供对命令的内置支持。命令在其基础实现中使用与输入相关的路由事件。它能够通过调用一个命令处理程序来处理相关的 UI 输入,如某个指针操作或特定加速键。

如果命令处理可用于 UI 元素,可以考虑使用它的命令处理 API 代替任何具体的输入事件。有关详细信息,请参阅 ButtonBase.Command

还可以实现 ICommand 来封装从普通事件处理程序中调用的命令功能。这样即使没有可用的 Command 属性,也能够使用命令。

文本输入和控件

某些控件通过自身的处理来对键盘事件作出响应。例如,TextBox 是一个控件,设计用于捕获然后在视觉上显示使用键盘输入的文本。它以自己的逻辑使用 KeyUpKeyDown 来捕获击键,然后,即使在文本实际上已更改的情况下,也还是会引发自己的 TextChanged 事件。

通常,仍然可以将 KeyUpKeyDown 的处理程序添加到 TextBox 或计划处理文本输入的任何相关控件中。但是,作为其预期设计,一个控件可能并不会对通过键事件指向它的所有键值作出响应。行为特定于每个控件。

例如,ButtonBaseButton 的基类)处理 KeyUp 以便可以检查空格键或 Enter 键。ButtonBase 认为 KeyUp 等同于按下鼠标左键以引发 Click 事件。事件的这一处理是在 ButtonBase 覆盖虚拟方法 OnKeyUp 时完成的。其实施过程中会将 Handled 设置为 true。如果空格键未接收到自己处理程序的 already-handled 事件,则结果为某个按钮的任意父按钮侦听键事件。

另一个示例是 TextBoxTextBox 不会将某些键(如箭头键)视为文本,而是视为特定于控件 UI 的行为。TextBox 将这些事件案例标记为已处理。

自定义控件可以通过重写 OnKeyDown/OnKeyUp 来为键事件实现自己的相似重写行为。如果你的自定义控件处理特定加速键或者具有类似于为 TextBox 描述的方案的控件或焦点行为,则应该将该逻辑放置在自己的 OnKeyDown/OnKeyUp 重写中。

触摸键盘

文本输入控件提供对触摸键盘的自动支持。当用户将输入焦点设置为使用触摸输入的文本控件时,触摸键盘会自动出现。当输入焦点不在文本控件上时,隐藏触摸键盘。

当出现触摸键盘时,会自动重新定位你的 UI 以确保可以看见具有焦点的元素。这可能会导致 UI 的其他重要区域移出屏幕。但是,你可以禁用默认行为并在出现触摸键盘时对自己的 UI 进行调整。有关详细信息,请参阅响应出现屏幕键盘的示例

如果创建需要文本输入,但并非从标准文本输入控件派生的自定义控件,则可以通过实现正确的 UI 自动化控件模式来添加触摸键盘支持。有关详细信息,请参阅触摸键盘示例

按下触摸键盘上的键引发 KeyDownKeyUp 事件,就像在硬件键盘上按下键一样。但是,触摸键盘不会引发 Ctrl+A、Ctrl+Z、Ctrl+X、Ctrl+C 和 Ctrl+V 的输入事件,这些是输入控件中保留的文本操作。

支持键盘交互的用户体验指南

下面是支持键盘交互的指南。

常规

  • 注意  窗口:

    用户应当能够仅使用硬件键盘或屏幕键盘完成你的应用支持的所有任务。
    注意  触摸键盘仅用于文本输入,并非用于应用或系统命令。
  • 当应用启动时,将初始键盘焦点设置在用户将首先直观(或最有可能)进行交互的元素上。通常,最合适的位置是应用的主要内容视图,以便用户可以立即使用箭头键滚动内容。有关将焦点设置为特定控件的详细信息,请参阅 Focus
  • 注意  窗口:

    请确保 Tab 和箭头键按照逻辑顺序在内容中移动。
  • 对于默认情况下未采用 Tab 键顺序的所有交互 UI 元素,将 TabIndex 属性设置为大于或等于 0 的值。设置 TabIndex 属性很重要,原因是屏幕读取器用户使用 Tab 键在交互 UI 元素之间导航。
  • 注意  窗口:

    使用箭头键作为在复合元素的子元素间进行正确的内部导航的键盘快捷方式。如果树状视图节点有单独的子元素,用于处理展开折叠和节点激活,则应使用左右箭头键提供键盘展开折叠功能。
  • 确保可以单击的每个 UI 元素也可以使用键盘进行调用。
  • 注意  窗口:

    为键盘应用功能实现键盘快捷方式。(快捷键是一套键组合,通过为用户提供一种可访问应用功能的高效方法来提高效率。)

    访问键是应用中 UI 元素的快捷键。它由 Alt 键和一个字母键组成。

    加速键是应用命令的快捷键。你的应用可以拥有与命令完全对应的 UI。加速键由 Ctrl 键和一个字母键组成。

    你必须为依靠屏幕阅读器和其他辅助技术的用户提供一种发现应用的快捷键的简单方法。使用 AccessKey 属性在应用的 HTML 标记中声明快捷键,并使用工具提示、辅助名称、辅助说明或某些其他屏幕通信形式传达快捷键。请记住将快捷键详细记录在应用的帮助内容中。

    有关实现快捷键的更多指南,请参阅 Windows 用户体验指南中的 快捷键

    不要重新定义用户期望在每个 Windows 应用商店应用内使用的默认键盘快捷键。请参阅键盘快捷键来获取完整列表。

硬件

查询键盘设备功能 (KeyboardCapabilities) 以确定是否连接键盘,并识别键盘硬件可以直接访问应用 UI 中的哪些方面。有关查询设备功能的详细信息,请参阅快速入门:标识指针设备

可将键盘按钮与你的应用中的相应 UI(向前和向后按钮)相关联。

视觉反馈

  • 仅在进行键盘交互时使用焦点矩形。如果用户开始使用触摸交互,则使键盘 UI 逐渐淡出。 这会使 UI 干净整洁。
  • 如果元素不支持交互(如静态文本),不要显示视觉反馈。
  • 对于所有代表相同输入目标的元素,同时显示视觉反馈。
  • 提供屏幕按钮(如 + 和 -)作为模拟基于触摸的操作 (如平移、旋转、缩放等)的提示。

有关视觉反馈的更一般指南,请参阅视觉反馈指南

相关主题

概念
响应用户交互
快速入门:添加 HTML 控件和处理事件
实现键盘辅助功能
使用 C++、C# 或 Visual Basic 的 Windows 应用商店应用中的辅助功能
显示和编辑文本
输入托管管理器和触摸键盘

 

 

显示:
© 2015 Microsoft