游戏板和遥控器交互

键盘和游戏板图像

各种交互体验可在游戏板、遥控器和键盘之间共享

在 Windows 应用程序中构建交互体验,以确保你的应用可供使用,并且可以通过电脑、便携式计算机和平板电脑的传统输入类型(鼠标、键盘、触摸等)以及电视和 Xbox 10 英尺体验的典型输入类型(例如游戏板和遥控器)进行访问。

请参阅针对 Xbox 和电视进行设计,了解 10 英尺体验中有关 Windows 应用程序的一般设计指导。

概述

在本主题中,我们将讨论你应该在交互设计中考虑的内容(或者不需要考虑的内容,如果平台已经涵盖这些内容),并提供指导和建议,用于构建无论设备、输入类型或者用户能力和首选项如何都方便使用的 Windows 应用程序。

最重要的一点,你的应用程序应在 2 英尺环境中直观且易于使用,就像在 10 英尺环境中一样(反之亦然)。 支持用户的首选设备,使 UI 焦点清晰且确定无疑、内容的排列方式使导航一致且可预测,并为用户提供尽可能短的路径。

注意

本主题中的大多数代码段都是以 XAML /C# 编写的;但其原则和概念适用于所有 Windows 应用。 如果你在开发适用于 Xbox 的 HTML/JavaScript Windows 应用,请查看 GitHub 上出色的 TVHelpers 库。

针对 2 英尺和 10 英尺体验进行优化

我们建议你至少对应用程序进行测试,以确保它们能在 2 英尺和 10 英尺方案中正常运行,并且所有功能都可以通过 Xbox 游戏板和遥控器发现和访问。

下面是一些其他方法,你可以通过这些方法优化你的应用,使其可在 2 英尺和 10 英尺体验中使用,并可通过所有输入设备(每个链接到本主题中的相应部分)优化。

注意

由于 Xbox 游戏板和遥控器支持许多 Windows 键盘行为和体验,因此,这些建议适用于这两种输入类型。 请参阅键盘交互,了解更多详细的键盘信息。

Feature 说明
XY 焦点导航和交互 “XY 焦点导航”使用户可以在应用的 UI 中进行导航。 但是,这让用户只能向上、向下、向左和向右导航。 本节概述了用于应对此事项和其他注意事项的建议。
鼠标模式 对于某些类型的应用程序(如地图或绘图和绘画应用)来说,XY 焦点导航不可行,甚至不可能。 在这些情况下,鼠标模式让用户能够使用游戏板或遥控器自由导航,就像电脑上的鼠标一样。
焦点视觉对象 焦点视觉对象是突出显示当前聚焦的 UI 元素的边框。 这有助于用户快速识别正在导航或与之交互的 UI。
焦点占用 “焦点占用”要求用户在 UI 元素具有焦点时,在游戏板或遥控器上按“A/选择”按钮,以便与其交互。
硬件按钮 游戏板和遥控器提供截然不同的按钮和配置。

游戏板和远程控制

就像键盘和鼠标适用于电脑一样,触摸适用于手机和平板电脑,游戏板和遥控器也是 10 英尺体验的主要输入设备。 本部分介绍硬件按钮及其用途。 在 XY 焦点导航和交互鼠标模式下,你将了解如何在这些输入设备时优化应用。

开箱即用的游戏板和远程行为的质量取决于应用中的键盘支持程度。 确保你的应用适用于游戏板/远程的一种好方法是确保它适用于电脑上的键盘,然后使用游戏板/远程进行测试,以在 UI 中查找薄弱点。

硬件按钮

在整个文档中,按钮将由下图中提供的名称引用。

游戏板和远程按钮关系图

如图所示,在远程控制上不支持的游戏板上支持某些按钮,反之亦然。 虽然可以使用仅在一个输入设备上支持的按钮来更快地导航 UI,但请注意,使用这些按钮进行关键交互可能会造成用户无法与 UI 的某些部分交互的情况。

下表列出了所有受 Windows 应用支持的硬件按钮,以及支持它们的输入设备。

按钮 游戏板 遥控器
A/Select 按钮
B/后退按钮
方向垫 (D-pad)
“菜单”按钮
视图按钮
X 和 Y 按钮
左摇杆
右摇杆
左右触发器
左右保险杠
OneGuide 按钮
“音量”按钮
通道按钮
媒体控件按钮
“静音”按钮

内置按钮支持

UWP 将现有键盘输入行为自动映射到游戏板和遥控器输入。 下表列出了这些内置映射。

键盘 游戏板/远程
箭头键 D-pad (也左摇杆在游戏板上)
空格键 A/Select 按钮
Enter A/Select 按钮
Escape B/后退按钮*

*当应用既不处理 B 按钮的 KeyDown 事件也不处理 KeyUp 事件时,将引发 SystemNavigationManager.BackRequested 事件,从而会导致应用内的向后导航。 但是,必须自行实现此目的,如以下代码片段所示:

// This code goes in the MainPage class

public MainPage()
{
    this.InitializeComponent();

    // Handling Page Back navigation behaviors
    SystemNavigationManager.GetForCurrentView().BackRequested +=
        SystemNavigationManager_BackRequested;
}

private void SystemNavigationManager_BackRequested(
    object sender,
    BackRequestedEventArgs e)
{
    if (!e.Handled)
    {
        e.Handled = this.BackRequested();
    }
}

public Frame AppFrame { get { return this.Frame; } }

private bool BackRequested()
{
    // Get a hold of the current frame so that we can inspect the app back stack
    if (this.AppFrame == null)
        return false;

    // Check to see if this is the top-most page on the app back stack
    if (this.AppFrame.CanGoBack)
    {
        // If not, set the event to handled and go back to the previous page in the
        // app.
        this.AppFrame.GoBack();
        return true;
    }
    return false;
}

注意

如果 B 按钮用于返回,则不要在 UI 中显示后退按钮。 如果使用 导航视图,则后退按钮将自动隐藏。 有关向后导航的更多信息,请参阅 Windows 应用的导航历史记录和向后导航

Xbox One 上的 Windows 应用还支持按“菜单”按钮来打开上下文菜单。 有关详细信息,请参阅 CommandBar 和 ContextFlyout

加速器支持

快捷键是可用于加速通过 UI 导航的按钮。 但是,这些按钮对特定输入设备可能是唯一的,因此请记住,并非所有用户都可以使用这些功能。 事实上,游戏板当前是 Xbox One 上唯一支持 Windows 应用加速器功能的输入设备。

下表列出了 UWP 中内置的加速器支持,以及可以自行实现的加速器支持。 利用自定义 UI 中的这些行为,提供一致的友好用户体验。

交互 键盘/鼠标 游戏板 内置用于: 推荐用于:
上一页/下一页 上一页/下一页 左/右触发器 CalendarViewListBoxListViewBaseListViewScrollViewerSelectorLoopingSelector、ComboBoxFlipView 支持垂直滚动的视图
页面左/右 左/右保险杠 ListBoxListViewBaseListViewScrollViewerSelectorLoopingSelectorFlipView 支持水平滚动的视图
放大/缩小 Ctrl +/- 左/右触发器 ScrollViewer,支持放大和缩小的视图
打开/关闭导航窗格 视图 导航窗格
Search Y 按钮 应用中主搜索函数的快捷方式
打开上下文菜单 右键单击 “菜单”按钮 ContextFlyout 上下文菜单

XY 焦点导航和交互

如果你的应用支持键盘的正确焦点导航,这将很好地转换为游戏板和远程控制。 使用箭头键的导航将 映射到 D 键 (以及 游戏板上的左摇杆 ),并且与 UI 元素的交互将 映射到 Enter/Select 键(请参阅 游戏板和远程控制)。

键盘和游戏板会使用许多事件和属性 - 它们会触发 KeyDownKeyUp 事件,并且两者仅导航到具有 IsTabStop="True"Visibility="Visible" 的控件。 有关键盘设计指南,请参阅 键盘交互

如果键盘支持正确实施,你的应用将正常工作;但是,可能需要一些额外的工作来支持每个方案。 考虑你的应用的特定需求,以尽可能提供最佳的用户体验。

重要

对于 Xbox One 上运行的 Windows 应用,默认会启用鼠标模式。 若要禁用鼠标模式并启用 XY 焦点导航,请设置 Application.RequiresPointerMode=WhenRequested

调试焦点问题

FocusManager.GetFocusedElement 方法将告诉你当前具有焦点的元素。 这对于焦点视觉对象位置可能不明显的情况非常有用。 可以将此信息记录到 Visual Studio 输出窗口,如下所示:

page.GotFocus += (object sender, RoutedEventArgs e) =>
{
    FrameworkElement focus = FocusManager.GetFocusedElement() as FrameworkElement;
    if (focus != null)
    {
        Debug.WriteLine("got focus: " + focus.Name + " (" +
            focus.GetType().ToString() + ")");
    }
};

XY 导航可能无法按预期方式工作有三个常见原因:

  • IsTabStopVisibility 属性设置错误。
  • 获取焦点的控件实际上比你想的要大 - XY 导航可看到控件的总大小(ActualWidthActualHeight),而不仅限于呈现关注内容的控件部分。
  • 一个可获得焦点的控件以其他控件为基础 - XY 导航不支持重叠显示的控件。

如果 XY 导航在修复这些问题后仍无法正常工作,则可以使用重写默认导航中所述的方法手动指向要获得焦点的元素。

如果 XY 导航按预期工作,但没有显示焦点视觉对象,则以下问题之一可能是原因:

  • 你重新模板化了控件,但不包含焦点视觉对象。 手动设置 UseSystemFocusVisuals="True" 或添加焦点视觉对象。
  • 通过调用 Focus(FocusState.Pointer)移动焦点。 FocusState 参数控制焦点视觉对象发生的情况。 一般情况下,应将其 FocusState.Programmatic设置为该对象,这将保持焦点视觉对象可见(如果之前可见),如果它以前处于隐藏状态,则将其隐藏。

本部分的其余部分详细介绍了使用 XY 导航时的常见设计挑战,并提供几种方法来解决这些问题。

无法访问的 UI

由于 XY 焦点导航会限制用户向上、向下、向左和向右移动,因此最终可能会出现 UI 部分无法访问的情况。 下图演示了 XY 焦点导航不支持的 UI 布局类型示例。 请注意,中间的元素是无法使用游戏板/远程访问的,因为垂直和水平导航的优先级将优先,中间元素永远不会足够高,无法获得焦点。

四个角中的元素,中间有不可访问的元素

如果由于某种原因无法重新排列 UI,请使用下一部分中讨论的方法来替代默认焦点行为。

重写默认导航

虽然通用 Windows 平台尝试确保 D-pad/左摇杆导航对用户有意义,但它不能保证针对应用的意图进行优化的行为。 确保为应用优化导航的最佳方式是使用游戏板对其进行测试,并确认用户能够以对应用场景有意义的方式访问每个 UI 元素。 如果应用的方案要求通过提供的 XY 焦点导航未实现的行为,请考虑遵循以下部分中的建议和/或重写行为,将焦点放在逻辑项上。

以下代码片段演示如何替代 XY 焦点导航行为:

<StackPanel>
    <Button x:Name="MyBtnLeft"
            Content="Search" />
    <Button x:Name="MyBtnRight"
            Content="Delete"/>
    <Button x:Name="MyBtnTop"
            Content="Update" />
    <Button x:Name="MyBtnDown"
            Content="Undo" />
    <Button Content="Home"  
            XYFocusLeft="{x:Bind MyBtnLeft}"
            XYFocusRight="{x:Bind MyBtnRight}"
            XYFocusDown="{x:Bind MyBtnDown}"
            XYFocusUp="{x:Bind MyBtnTop}" />
</StackPanel>

在这种情况下,当焦点位于按钮上 Home 并且用户导航到左侧时,焦点将移动到 MyBtnLeft 按钮;如果用户导航到右侧,焦点将移动到 MyBtnRight 按钮,依此类移。

若要防止焦点从某个方向的控件移动,请使用 XYFocus* 该属性将其指向同一控件:

<Button Name="HomeButton"  
        Content="Home"  
        XYFocusLeft ="{x:Bind HomeButton}" />

XYFocus使用这些属性,除非具有焦点的子级使用同XYFocus一属性,否则当下一个焦点候选项离开其可视化树时,控件父级还可以强制导航其子级。

<StackPanel Orientation="Horizontal" Margin="300,300">
    <UserControl XYFocusRight="{x:Bind ButtonThree}">
        <StackPanel>
            <Button Content="One"/>
            <Button Content="Two"/>
        </StackPanel>
    </UserControl>
    <StackPanel>
        <Button x:Name="ButtonThree" Content="Three"/>
        <Button Content="Four"/>
    </StackPanel>
</StackPanel>

在上面的示例中,如果焦点位于 Button Two 上,并且用户导航到右侧,则最佳焦点候选项为 Button “四”;但是,焦点将移动到 Button “三”,因为父级 UserControl 强制它在从可视化树中移出时导航到该位置。

最少单击的路径

尝试允许用户在单击次数最少时执行最常见的任务。 在以下示例中,TextBlock 放置在“播放”按钮(最先得到焦点)和常用元素之间,因此不必要的元素放置在优先任务之间。

导航最佳做法提供最少单击的路径

在以下示例中,TextBlock 改为放置在“播放”按钮上方。 只需重新排列 UI,以便在优先级任务之间不放置不必要的元素将极大地提高应用的可用性。

TextBlock 在“播放”按钮上方移动,使其不再位于优先级任务之间

CommandBar 和 ContextFlyout

使用 CommandBar 时,请记住在问题: 位于长时间滚动列表/网格之后的 UI 元素中滚动浏览列表的问题。 下图显示了具有列表/网格底部的 UI 布局 CommandBar 。 用户需要一直向下滚动到列表/网格才能到达 CommandBar

列表/网格底部的 CommandBar

如果将列表/网格放在CommandBar上面,该怎么办? 虽然向下滚动列表/网格的用户必须向上滚动才能到达 CommandBar,但它的导航略低于以前的配置。 请注意,假设应用的初始焦点位于列表/网格下方或上方 CommandBar;如果初始焦点位于列表/网格下方,此方法将不起作用。 如果这些项目 CommandBar 是不需要经常访问的全局操作项(例如 “同步 ”按钮),那么在列表/网格上方可以接受它们。

虽然不能垂直堆叠 CommandBar项,但将它们放置在滚动方向(例如,垂直滚动列表的左侧或右侧,或水平滚动列表的顶部或底部)是另一个选项,你可以考虑它是否适用于 UI 布局。

如果你的应用具有 CommandBar 可供用户轻松访问其项,则可能需要考虑将这些项 放在 ContextFlyout 中并从中删除 CommandBar它们。 ContextFlyoutUIElement 的属性,并且是与该元素关联的上下文菜单。 在电脑上,右键单击具有 a 的 ContextFlyout元素时,将弹出该上下文菜单。 在 Xbox One 上,如果焦点在此类元素上,按“菜单”按钮也会发生此行为。

UI 布局挑战

由于 XY 焦点导航的性质,某些 UI 布局更具挑战性,应逐个逐个评估。 虽然没有单一的“正确”方法,你选择哪种解决方案符合应用的特定需求,但有一些技术可用于提供出色的电视体验。

为了更好地了解这一点,让我们看看一个虚构的应用,该应用说明了一些这些问题和技术来克服这些问题和技术。

注意

此虚假应用旨在说明 UI 问题和潜在解决方案,并不适合显示特定应用的最佳用户体验。

下面是一个虚构的房地产应用,其中显示了可供销售的房屋列表、地图、房产说明和其他信息。 此应用提出了三种挑战,你可以使用以下技术来克服这些挑战:

假房地产应用

问题:位于长时间滚动列表/网格之后的 UI 元素

下图 中显示的属性的 ListView 是一个非常长的滚动列表。 如果用户导航到列表时不需要ListView参与,焦点将放在列表中的第一个项目上。 要使用户能够访问 “上一个 ”或 “下一步 ”按钮,他们必须浏览列表中的所有项。 在这种难以要求用户遍历整个列表(即,列表太长,无法接受此体验的情况),你可能希望考虑其他选项。

房地产应用:包含 50 个项目的列表需要 51 次单击即可访问下面的按钮

解决方案

UI 重新排列

除非初始焦点放置在页面底部,否则放置在长滚动列表上方的 UI 元素通常比放置在下方更容易访问。 如果此新布局适用于其他设备,则更改所有设备系列的布局,而不是仅为 Xbox One 执行特殊的 UI 更改可能是一种成本较低的方法。 此外,将 UI 元素放置在滚动方向(即水平滚动列表或垂直滚动列表)将使更好的辅助功能。

房地产应用:将按钮置于长滚动列表上方

焦点占用

需要参与时,整个ListView都将成为单个焦点目标。 用户将能够绕过列表的内容,以访问下一个可聚焦元素。 详细了解哪些控件支持参与以及如何在 Focus engagement 中使用它们。

房地产应用:将预订设置为必需,以便只需单击 1 次即可到达“上一/下一步”按钮

问题:无任何可聚焦元素的 ScrollViewer

由于 XY 焦点导航依赖于一次导航到一个可聚焦的 UI 元素, 因此不包含任何可聚焦元素的 ScrollViewer (如仅包含文本的一个,如本示例中所示)可能会导致用户无法查看其中 ScrollViewer的所有内容的情况。 有关此方案和其他相关方案的解决方案,请参阅 焦点参与

房地产应用:仅包含文本的 ScrollViewer

问题:自由滚动 UI

当你的应用需要自由滚动的 UI(如绘图图面)或在此示例中,地图、XY 焦点导航根本不起作用。 在这种情况下,可以打开 鼠标模式 ,以允许用户在 UI 元素内自由导航。

使用鼠标模式映射 UI 元素

鼠标模式

如 XY 焦点导航和交互中所述,在 Xbox One 上,焦点通过使用 XY 导航系统移动,允许用户通过向上、向下、向左和向右移动将焦点从控件转移到控件。 但是,某些控件(如 WebViewMapControl)需要类似鼠标的交互,用户可在控件边界内自由移动指针。 还有一些应用,用户能够跨整个页面移动指针是有意义的,具有游戏板/远程体验,类似于用户可以使用鼠标在电脑上找到的内容。

对于这些方案,应请求整个页面的指针(鼠标模式),或在页面内的控件上。 例如,你的应用可以有一 WebView 个页面,该页面仅在控件内部使用鼠标模式,而 XY 焦点导航位于其他位置。 若要请求指针,可以在控件或页面参与时或页面具有焦点时指定它

注意

当控件获得焦点时请求指针。

对于在 Xbox One 上运行的 XAML 和托管 Web 应用,默认情况下,整个应用的鼠标模式处于打开状态。 强烈建议关闭此功能,并针对 XY 导航优化应用。 为此,请将 Application.RequiresPointerMode 属性设置为 WhenRequested 仅在控件或页面调用鼠标模式时启用鼠标模式。

若要在 XAML 应用中执行此操作,请在类中使用 App 以下代码:

public App()
{
    this.InitializeComponent();
    this.RequiresPointerMode =
        Windows.UI.Xaml.ApplicationRequiresPointerMode.WhenRequested;
    this.Suspending += OnSuspending;
}

有关详细信息,包括 HTML/JavaScript 的示例代码,请参阅 如何禁用鼠标模式

下图显示了鼠标模式下游戏板/远程的按钮映射。

鼠标模式下游戏板/远程的按钮映射

注意

鼠标模式仅在具有游戏板/远程的 Xbox One 上受支持。 在其他设备系列和输入类型上,它将被无提示忽略。

使用控件或页面上的 RequiresPointer 属性激活其上的鼠标模式。 此属性有三个可能的值: Never (默认值) WhenEngagedWhenFocused

在控件上激活鼠标模式

当用户使用某个控件 RequiresPointer="WhenEngaged"时,鼠标模式在控件上激活,直到用户取消它。 以下代码片段演示了一个简单的 MapControl 代码片段,用于激活鼠标模式:

<Page>
    <Grid>
        <MapControl IsEngagementRequired="true"
                    RequiresPointer="WhenEngaged"/>
    </Grid>
</Page>

注意

如果控件在参与时激活鼠标模式,则还必须使用鼠标模式 IsEngagementRequired="true";否则,将永远不会激活鼠标模式。

当控件处于鼠标模式时,其嵌套控件也将处于鼠标模式。 将忽略它的子元素的请求模式 - 当父元素处于鼠标模式下,子元素也必须处于鼠标模式下。

此外,仅当控件获得焦点时,才会检查控件请求的模式,因此模式在具有焦点时不会动态更改。

在页面上激活鼠标模式

当页面具有属性 RequiresPointer="WhenFocused"时,当获得焦点时,将为整个页面激活鼠标模式。 以下代码片段演示如何为页面提供此属性:

<Page RequiresPointer="WhenFocused">
    ...
</Page>

注意

该值WhenFocused仅在 Page 对象上受支持。 如果尝试在控件上设置此值,将引发异常。

禁用全屏内容的鼠标模式

通常在全屏显示视频或其他类型的内容时,需要隐藏光标,因为它会分散用户的注意力。 当应用的其余部分使用鼠标模式时,会出现这种情况,但希望在显示全屏内容时将其关闭。 为此,请自行 Page放置全屏内容,并按照以下步骤操作。

  1. 在对象中 App ,设置 RequiresPointerMode="WhenRequested"
  2. 在除全屏Page以外的每个Page对象中,设置RequiresPointer="WhenFocused"
  3. 对于全屏 Page,请设置 RequiresPointer="Never"

这样,在显示全屏内容时,光标永远不会显示。

焦点视觉对象

焦点视觉对象是当前具有焦点的 UI 元素周围的边框。 这有助于使用户能够轻松地导航 UI,而不会丢失。

随着视觉更新和大量自定义选项添加到焦点视觉对象,开发人员可以信任单个焦点视觉对象在电脑和 Xbox One 以及支持键盘和/或游戏板/远程的任何其他 Windows 设备上都能正常工作。

虽然同一焦点视觉对象可用于不同的平台,但用户遇到该视觉对象的上下文对于 10 英尺的体验略有不同。 应假定用户未完全关注整个电视屏幕,因此,当前聚焦元素始终对用户清晰可见,以避免搜索视觉对象的挫折感非常重要。

请记住,在使用游戏板或远程控件时,默认情况下,焦点视觉对象会显示,但 不会 显示键盘。 因此,即使你未实现它,在 Xbox One 上运行应用时也会显示它。

初始焦点视觉放置

启动应用或导航到页面时,将焦点放在 UI 元素上,该元素是用户将对其执行操作的第一个元素有意义的。 例如,照片应用可能会将焦点放在库中的第一个项目上,并且导航到歌曲的详细视图的音乐应用可能会将焦点放在播放按钮上,以便轻松播放音乐。

尝试将初始焦点放在应用的左上角区域(或从右到左流的右上角)。 大多数用户倾向于首先关注该角落,因为这是应用内容流通常开始的地方。

使焦点清晰可见

一个焦点视觉对象应始终在屏幕上可见,以便用户可以在不搜索焦点的情况下选取离开的位置。 同样,屏幕上应始终存在可聚焦的项 — 例如,不要使用仅带有文本而没有可聚焦元素的弹出窗口。

此规则的例外情况是全屏体验,例如观看视频或查看图像,在这种情况下,不合适显示焦点视觉对象。

显示焦点

显示焦点是一种照明效果,当用户将游戏板或键盘焦点移动到它们时,可对可聚焦元素(如按钮)的边框进行动画处理。 通过对聚焦元素边框周围的发光进行动画处理,“显示焦点”可让用户更好地了解焦点的位置和焦点的位置。

默认情况下,“显示焦点”处于关闭状态。 对于 10 英尺的体验,应选择在应用构造函数中设置 Application.FocusVisualKind 属性 来显示焦点。

    if(AnalyticsInfo.VersionInfo.DeviceFamily == "Windows.Xbox")
    {
        this.FocusVisualKind = FocusVisualKind.Reveal;
    }

有关详细信息,请参阅“展示焦点”指南

自定义焦点视觉对象

如果要自定义焦点视觉对象,可以通过修改与每个控件的焦点视觉对象相关的属性来执行此操作。 可以使用多种此类属性对应用进行个性化设置。

甚至可以选择退出系统提供的焦点视觉对象,方法是使用视觉状态绘制自己的视觉对象。 若要了解详细信息,请参阅 VisualState

浅色消除覆盖

为了将用户的注意力吸引到用户当前正在使用游戏控制器或遥控器操作的 UI 元素上,当应用在 Xbox One 上运行时,UWP 会自动添加“烟”层,该层覆盖弹出窗口 UI 之外的区域。 这无需额外工作,但在设计 UI 时需要牢记这一点。 可以在任意FlyoutBase位置设置属性LightDismissOverlayMode以启用或禁用冒烟层;默认Auto为该属性,这意味着它在 Xbox 上启用,并在其他位置禁用。 有关详细信息,请参阅 模式与浅色消除

焦点占用

焦点参与旨在使使用游戏板或远程程序更轻松地与应用交互。

注意

设置焦点参与不会影响键盘或其他输入设备。

当 FrameworkElement 对象上的属性IsFocusEngagementEnabled设置为True时,它将控件标记为需要焦点参与。 这意味着用户必须按“A/选择”按钮来“占用”该控件,并与其交互。 当用户完成操作时,他们可以按“B/后退”按钮脱离该控件,并导航离开。

注意

IsFocusEngagementEnabled 是一个新的 API,尚未介绍。

焦点捕获

焦点捕获是当用户尝试导航应用的 UI 但被“捕获”在控件内时会发生什么情况,使得难以甚至不可能在控件外部移动。

以下示例演示创建焦点捕获的 UI。

水平滑块左侧和右侧的按钮

如果用户想要从左侧按钮导航到右侧按钮,则假定他们必须执行的所有操作都是在 D-pad/左侧摇杆上按两次是合乎逻辑的。 但是,如果 滑块 不需要参与,将发生以下行为:当用户第一次按下时,焦点将转移到 Slider该位置,当焦点再次按下时, Slider其句柄将移动到右侧。 用户将继续向右移动句柄,并且无法转到该按钮。

可通过多种方法来解决此问题。 一个是设计不同的布局,类似于 XY 焦点导航和交互中的房地产应用示例,我们将上一个按钮和下一个按钮重新定位ListView上面。 垂直堆叠控件,而不是水平堆叠,如下图所示可以解决问题。

水平滑块上方和下方的按钮

现在,用户可以通过按 D 键/左摇杆向上和向下键导航到每个控件,当具有焦点时 Slider ,他们可以按左和向右移动控点,按预期方式移动 Slider 手柄。

解决此问题的另一种方法是需要参与 Slider这个问题。 如果设置 IsFocusEngagementEnabled="True",这将导致以下行为。

要求焦点参与滑块,以便用户可以导航到右侧的按钮

Slider当需要焦点参与时,用户只需在 D 键/左摇杆上按两次即可进入右侧的按钮。 此解决方案非常出色,因为它不需要 UI 调整并生成预期行为。

项控件

除了滑块控件之外,还有其他可能需要参与的控件,例如:

Slider与控件不同,这些控件本身不会捕获焦点;但是,当它们包含大量数据时,它们可能会导致可用性问题。 下面是包含大量数据的 ListView 一个示例。

包含大量数据和下方按钮的 ListView

与示例 Slider 类似,我们尝试使用游戏板/遥控器从顶部的按钮导航到底部的按钮。 从焦点放在顶部按钮开始,按下 D 键/摇杆会将焦点放在第一个项目上 ListView (“项目 1”)。 当用户再次按下时,列表中的下一项将获得焦点,而不是底部的按钮。 若要转到该按钮,用户必须在第一个项中 ListView 导航。 ListView如果包含大量数据,这可能是不方便的,而不是最佳的用户体验。

若要解决此问题,请将属性设置为需要参与该属性IsFocusEngagementEnabled="True"ListView。 这样,用户只需按下即可快速跳过。ListView 但是,他们将无法滚动浏览列表或从中选择项,除非他们占用该列表,方法是在具有焦点时按“A/选择”按钮,然后按“B/后退”按钮来脱离。

需要预订的 ListView

ScrollViewer

与这些控件略有不同,这是 ScrollViewer,它有自己的怪癖需要考虑。 如果你有 ScrollViewer 具有可聚焦内容,则默认情况下导航到 ScrollViewer 将允许你浏览其可聚焦元素。 与在一起 ListView,必须滚动浏览每个项才能在外部 ScrollViewer导航。

如果 ScrollViewer 没有 可聚焦内容(例如,如果它仅包含文本),则可以设置 IsFocusEngagementEnabled="True",以便用户可以通过使用“A/选择”按钮占用 ScrollViewer 在用户已占用后,他们可以通过使用方向键/左摇杆滚动浏览文本,然后在他们完成后按“B/后退”按钮来脱离。

另一个方法是在 ScrollViewer 上设置 IsTabStop="True",以便当 ScrollViewer 内不存在可聚焦元素时,用户无需占用控件。他们只需将焦点放置在该控件上,然后使用方向键/左摇杆进行滚动。

焦点参与默认值

某些控件会导致焦点捕获通常足以保证其默认设置需要焦点参与,而其他控件默认关闭焦点参与度,但可以从打开焦点中获益。 下表列出了这些控件及其默认焦点参与行为。

控制 焦点参与默认值
CalendarDatePicker
FlipView
GridView
ListBox
ListView
ScrollViewer
SemanticZoom
滑块

IsFocusEngagementEnabled="True" 时,所有其他 Windows 控件都不会导致任何行为或视觉更改。

总结

你可以构建针对特定设备或体验进行了优化的 Windows 应用程序,但通用 Windows 平台还允许你构建可在 2 英尺和 10 英尺体验中跨设备成功使用的应用,而不管输入设备或用户能力如何。 使用本文中的建议可以确保你的应用可在电视和电脑上正常工作。