命令栏浮出控件

使用命令栏浮出控件时,可以在浮动工具栏中显示与 UI 画布上的某个元素相关的命令,方便用户访问常见任务。

An expanded text command bar flyout

CommandBar 一样,CommandBarFlyout 的 PrimaryCommandsSecondaryCommands 属性可以用来添加命令。 可以将命令置于这两个集合中,或者置于其中的一个中。 主要命令和辅助命令何时显示以及以何种方式显示取决于显示模式。

命令栏浮出控件有两个显示模式:折叠和展开。

  • 在折叠模式下,仅显示主要命令。 如果命令栏浮出控件包含主要命令和辅助命令,则会显示由省略号 [...] 表示的“查看更多”按钮。 这样用户就可以通过切换到展开模式来访问辅助命令。
  • 在展开模式下,主要命令和辅助命令都会显示。 (如果此控件只有辅助项,则这些辅助项的显示方式类似于 MenuFlyout 控件。)

这是正确的控件吗?

使用命令栏浮出控件,可以在应用画布的元素上下文中为用户显示一系列命令,例如按钮和菜单项。

建议使用命令栏浮出控件来创建上下文菜单。 这允许将与上下文菜单的场景最相关的常用命令(例如复制、剪切、粘贴、删除、共享或文本选择命令)添加为主要命令,以便这些命令在命令栏浮出控件中显示为单一的水平行。 TextCommandBarFlyout 已正确配置为在 TextBox、TextBlock、RichEditBox、RichTextBlock 和 PasswordBox 控件中自动显示文本命令。 CommandBarFlyout 可用于替换文本控件上的默认文本命令。

若要在列表项上显示上下文命令,请按用于集合和列表的上下文命令中的指南操作。

主动调用与被动调用

通常可以通过两种方式来调用与 UI 画布上的某个元素相关联的浮出控件或菜单:主动调用和被动调用。

在主动调用中,当用户与项交互时,与该项关联的命令会自动显示。 例如,当用户选择文本框中的文本时,文本格式设置命令可能会弹出。 在这种情况下,命令栏浮出控件不占据焦点位置, 而是为与用户进行交互的项呈现相关命令。 如果用户不与这些命令交互,这些命令会被取消。

在被动调用中,只有在用户通过显式操作(例如右键单击)来请求命令时,命令才会显示。 这对应于传统的上下文菜单概念。

可以通过任一方式使用 CommandBarFlyout,甚至可以将这两种方式混合使用。

UWP 和 WinUI 2

重要

本文中的信息和示例针对使用 Windows 应用 SDKWinUI 3 的应用进行优化,但通常适用于使用 WinUI 2 的 UWP 应用。 有关平台特定信息和示例,请参阅 UWP API 参考。

本部分包含需要在 UWP 或 WinUI 2 应用中使用该控件的信息。

UWP 应用的 CommandBarFlyout 控件包含在 Windows UI 库 2 中。 有关详细信息(包括安装说明),请参阅 Windows UI 库。 此控件的 API 存在于Windows中。UI。Xaml.Controls (UWP) 和 Microsoft.UI.Xaml.Controls (WinUI) 命名空间。

建议使用最新的 WinUI 2 来获取所有控件的最新样式和模板。 WinUI 2.2 或更高版本包含此控件的新模板,该模板使用圆角。 有关详细信息,请参阅圆角半径

若要将本文中的代码与 WinUI 2 配合使用,请使用 XAML 中的别名, (我们使用muxc) 来表示项目中包括的 Windows UI 库 API。 有关详细信息,请参阅 WinUI 2 入门

xmlns:muxc="using:Microsoft.UI.Xaml.Controls"

<muxc:CommandBarFlyout />

创建命令栏浮出控件

WinUI 3 库应用包括大多数 WinUI 3 控件、特性和功能的交互式示例。 从Microsoft Store获取应用,或在GitHub上获取源代码

以下示例介绍了如何创建命令栏浮出控件并以主动和被动两种方式使用它。 点击图像时,浮出控件以折叠模式显示。 作为上下文菜单显示时,浮出控件以展开模式显示。 不管哪一种情况,用户都可以在浮出控件打开后将其展开或折叠。

<Grid>
    <Grid.Resources>
        <CommandBarFlyout x:Name="ImageCommandsFlyout">
            <AppBarButton Icon="OutlineStar" ToolTipService.ToolTip="Favorite"/>
            <AppBarButton Icon="Copy" ToolTipService.ToolTip="Copy"/>
            <AppBarButton Icon="Share" ToolTipService.ToolTip="Share"/>
            <CommandBarFlyout.SecondaryCommands>
                <AppBarButton Label="Select all"/>
                <AppBarButton Label="Delete" Icon="Delete"/>
            </CommandBarFlyout.SecondaryCommands>
        </CommandBarFlyout>
    </Grid.Resources>

    <Image Source="Assets/image1.png" Width="300"
           Tapped="Image_Tapped" FlyoutBase.AttachedFlyout="{x:Bind ImageCommandsFlyout}"
           ContextFlyout="{x:Bind ImageCommandsFlyout}"/>
</Grid>
private void Image_Tapped(object sender, TappedRoutedEventArgs e)
{
    var flyout = FlyoutBase.GetAttachedFlyout((FrameworkElement)sender);
    var options = new FlyoutShowOptions()
    {
        // Position shows the flyout next to the pointer.
        // "Transient" ShowMode makes the flyout open in its collapsed state.
        Position = e.GetPosition((FrameworkElement)sender),
        ShowMode = FlyoutShowMode.Transient
    };
    flyout?.ShowAt((FrameworkElement)sender, options);
}

下面是处于折叠状态的命令栏浮出控件。

Example of a collapsed command bar flyout

下面是显示辅助命令的扩展状态中的相同命令栏浮出控件。

Example of an expanded command bar flyout

主动显示命令

主动显示上下文命令时,默认情况下只应显示主要命令(命令栏浮出控件应该折叠)。 请将最重要的命令置于主要命令集合中,将其他会按传统方式进入上下文菜单中的命令置于辅助命令集合中。

若要主动显示命令,通常需要通过处理 ClickTapped 事件来显示命令栏浮出控件。 将浮出控件的 ShowMode 设置为 TransientTransientWithDismissOnPointerMoveAway 可以在折叠模式下打开浮出控件,不获取焦点。

文本控件具有 SelectionFlyout 属性。 为此属性分配浮出控件后,当文本处于选中状态时,该控件就会自动显示。

被动显示命令

被动显示上下文命令时,默认情况下会显示充当上下文菜单的辅助命令(命令栏浮出控件应该展开)。 在这种情况下,命令栏浮出控件可能有主要命令和辅助命令,也可能只有辅助命令。

若要在上下文菜单中显示命令,通常需将浮出控件分配给 UI 元素的 ContextFlyout 属性。 这样就可以由该元素负责打开浮出控件,你不需执行任何其他操作。

如果你自己负责显示浮出控件(例如,在出现 RightTapped 事件时这样做),请将浮出控件的 ShowMode 设置为 Standard,以便在展开模式下打开浮出控件并为其提供焦点。

提示

若要详细了解显示浮出控件时的选项以及如何控制浮出控件的放置,请参阅浮出控件

显示始终展开的 CommandBarFlyout

在 CommandBarFlyout 中有主要命令和辅助命令时,默认显示“查看更多”[...] 按钮,可用于展开和折叠辅助命令。 如果你想将 CommandBarFlyout 保持在展开模式并始终显示辅助命令,则可以使用 CommandBarFlyout.AlwaysExpanded 属性。

AlwaysExpanded 属性设置为时 true,不会显示“查看更多”按钮,并且用户无法切换控件的展开状态。 单击辅助命令或用户单击浮出控件外部时,CommandBarFlyout 仍将正常关闭。

仅当 CommandBarFlyout 具有辅助命令时,此属性才有效。 如果没有辅助命令,则 CommandBarFlyout 将始终处于折叠模式。

提示

即使 AlwaysExpanded 属性设置为 true,仍然可以通过设置 IsOpen 属性来以编程方式折叠和展开 CommandBarFlyout。

命令和内容

CommandBarFlyout 控件有 2 个可用于添加命令和内容的属性:PrimaryCommandsSecondaryCommands

默认情况下,添加到命令栏中的项目也会添加到 PrimaryCommands 集合中 。 这些命令显示在命令栏中,在折叠模式和展开模式下均可见。 与 CommandBar 不同,主要命令不会自动溢出到辅助命令,可能会被截断。

也可将命令添加到 SecondaryCommands 集合中 。 辅助命令显示在控件的菜单部分,仅在展开模式下可见。

如果有对场景很重要的常用命令(如复制、剪切、粘贴、删除、共享或文本选择命令),建议将这些命令添加为主命令,而不是辅助命令。

应用栏按钮

可以直接使用 AppBarButtonAppBarToggleButtonAppBarSeparator 控件填充 PrimaryCommands 和 SecondaryCommands。

应用栏按钮控件以一个图标和文本标签为特征。 这些控件经优化后适合在命令栏中使用,其外观会变化,具体取决于控件是显示在命令栏中还是显示在溢出菜单中。

  • 用作主要命令的应用栏按钮在应用栏中显示时只有其图标;文本标签未显示。 建议使用 工具提示 显示命令的文本说明,如下所示。
    <AppBarButton Icon="Copy" ToolTipService.ToolTip="Copy"/>
    
  • 用作辅助命令的应用栏按钮显示在菜单中,标签和图标均可见。

图标

请考虑提供菜单项图标:

  • 最常使用的项。
  • 图标为标准或知名的菜单项。
  • 图标可明确说明命令功能的菜单项。

对于没有标准可视化的命令可不必提供图标。 加密图标没有帮助,需创建可视的待筛选邮件,并阻止用户关注重要菜单项。

其他内容

可以将其他控件添加到命令栏浮出控件中,只需将它们包装在 AppBarElementContainer 中即可。 这样就可以添加 DropDownButtonSplitButton 之类的控件,或者添加 StackPanel 之类的容器,以便创建更复杂的 UI。

元素必须实现 ICommandBarElement 接口才能添加到命令栏浮出控件的主要命令或辅助命令集合中。 AppBarElementContainer 是实现此接口的包装器,因此即使它不实现接口本身,也可以向命令栏添加元素。

在这里,使用了 AppBarElementContainer 将额外元素添加到命令栏浮出控件。 为主要命令添加了 SplitButton,用于选择颜色。 为辅助命令添加了 StackPanel,以便为缩放控件实现更复杂的布局。

提示

默认情况下,为应用画布设计的元素可能会在应用栏中显示不正常。 使用 AppBarElementContainer 添加某个元素时,应该执行某些步骤,使该元素与其他命令栏元素匹配:

  • 使用轻型样式设置覆盖默认的画笔,使该元素的背景和边框与应用栏按钮匹配。
  • 调整元素的大小和位置。
  • 将图标包装在宽度和高度为 16px 的 Viewbox 中。

注意

此示例仅显示命令栏浮出控件 UI,并未实现任何显示的命令。 若要详细了解如何实现这些命令,请参阅按钮命令设计基础知识

<CommandBarFlyout>
    <AppBarButton Icon="Cut" ToolTipService.ToolTip="Cut"/>
    <AppBarButton Icon="Copy" ToolTipService.ToolTip="Copy"/>
    <AppBarButton Icon="Paste" ToolTipService.ToolTip="Paste"/>
    <!-- Alignment controls -->
    <AppBarElementContainer>
         <SplitButton ToolTipService.ToolTip="Alignment">
            <SplitButton.Resources>
                <!-- Override default brushes to make the SplitButton 
                     match other command bar elements. -->
                <Style TargetType="SplitButton">
                    <Setter Property="Height" Value="38"/>
                </Style>
                <SolidColorBrush x:Key="SplitButtonBackground"
                                 Color="Transparent"/>
                <SolidColorBrush x:Key="SplitButtonBackgroundPressed"
                                 Color="{ThemeResource SystemListMediumColor}"/>
                <SolidColorBrush x:Key="SplitButtonBackgroundPointerOver"
                                 Color="{ThemeResource SystemListLowColor}"/>
                <SolidColorBrush x:Key="SplitButtonBorderBrush" Color="Transparent"/>
                <SolidColorBrush x:Key="SplitButtonBorderBrushPointerOver"
                                 Color="Transparent"/>
                <SolidColorBrush x:Key="SplitButtonBorderBrushChecked"
                                 Color="Transparent"/>
            </SplitButton.Resources>
            <SplitButton.Content>
                <Viewbox Width="16" Height="16" Margin="0,2,0,0">
                    <SymbolIcon Symbol="AlignLeft"/>
                </Viewbox>
            </SplitButton.Content>
            <SplitButton.Flyout>
                <MenuFlyout>
                    <MenuFlyoutItem Icon="AlignLeft" Text="Align left"/>
                    <MenuFlyoutItem Icon="AlignCenter" Text="Center"/>
                    <MenuFlyoutItem Icon="AlignRight" Text="Align right"/>
                </MenuFlyout>
            </SplitButton.Flyout>
        </SplitButton>
    </AppBarElementContainer>
    <!-- end Alignment controls -->
    <CommandBarFlyout.SecondaryCommands>
        <!-- Zoom controls -->
        <AppBarElementContainer>
            <AppBarElementContainer.Resources>
                <!-- Override default brushes to make the Buttons
                     match other command bar elements. -->
                <SolidColorBrush x:Key="ButtonBackground"
                                 Color="Transparent"/>
                <SolidColorBrush x:Key="ButtonBackgroundPressed"
                                 Color="{ThemeResource SystemListMediumColor}"/>
                <SolidColorBrush x:Key="ButtonBackgroundPointerOver"
                                 Color="{ThemeResource SystemListLowColor}"/>
                <SolidColorBrush x:Key="ButtonBorderBrush"
                                 Color="Transparent"/>
                <SolidColorBrush x:Key="ButtonBorderBrushPointerOver"
                                 Color="Transparent"/>
                <SolidColorBrush x:Key="ButtonBorderBrushChecked"
                                 Color="Transparent"/>
                <Style TargetType="TextBlock">
                    <Setter Property="VerticalAlignment" Value="Center"/>
                </Style>
                <Style TargetType="Button">
                    <Setter Property="Height" Value="40"/>
                    <Setter Property="Width" Value="40"/>
                </Style>
            </AppBarElementContainer.Resources>
            <Grid Margin="12,-4">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="Auto"/>
                    <ColumnDefinition Width="76"/>
                    <ColumnDefinition Width="Auto"/>
                </Grid.ColumnDefinitions>
                <Viewbox Width="16" Height="16" Margin="0,2,0,0">
                    <SymbolIcon Symbol="Zoom"/>
                </Viewbox>
                <TextBlock Text="Zoom" Margin="10,0,0,0" Grid.Column="1"/>
                <StackPanel Orientation="Horizontal" Grid.Column="2">
                    <Button ToolTipService.ToolTip="Zoom out">
                        <Viewbox Width="16" Height="16">
                            <SymbolIcon Symbol="ZoomOut"/>
                        </Viewbox>
                    </Button>
                    <TextBlock Text="50%" Width="40"
                               HorizontalTextAlignment="Center"/>
                    <Button ToolTipService.ToolTip="Zoom in">
                        <Viewbox Width="16" Height="16">
                            <SymbolIcon Symbol="ZoomIn"/>
                        </Viewbox>
                    </Button>
                </StackPanel>
            </Grid>
        </AppBarElementContainer>
        <!-- end Zoom controls -->
        <AppBarSeparator/>
        <AppBarButton Label="Undo" Icon="Undo"/>
        <AppBarButton Label="Redo" Icon="Redo"/>
        <AppBarButton Label="Select all" Icon="SelectAll"/>
    </CommandBarFlyout.SecondaryCommands>
</CommandBarFlyout>

下面是具有打开的 SplitButton 的折叠命令栏浮出控件。

A command bar flyout with a split button

下面是菜单中具有自定义缩放 UI 的展开命令栏浮出控件。

A command bar flyout with complex UI

创建仅包含辅助命令的上下文菜单

你可以使用仅带有辅助命令的命令栏弹出来创建上下文菜单,以实现与菜单浮出控件相同的外观和行为。

<Grid>
    <Grid.Resources>
        <!-- A command bar flyout with only secondary commands. -->
        <CommandBarFlyout x:Name="ContextMenu">
            <CommandBarFlyout.SecondaryCommands>
                <AppBarButton Label="Copy" Icon="Copy"/>
                <AppBarButton Label="Save" Icon="Save"/>
                <AppBarButton Label="Print" Icon="Print"/>
                <AppBarSeparator />
                <AppBarButton Label="Properties"/>
            </CommandBarFlyout.SecondaryCommands>
        </CommandBarFlyout>
    </Grid.Resources>

    <Image Source="Assets/image1.png" Width="300"
           ContextFlyout="{x:Bind ContextMenu}"/>
</Grid>

下面是命令栏浮出控件作为上下文菜单。

A command bar flyout with only secondary commands

也可将 CommandBarFlyout 与 DropDownButton 配合使用来创建标准菜单。

<CommandBarFlyout>
    <AppBarButton Icon="Placeholder"/>
    <AppBarElementContainer>
        <DropDownButton Content="Mail">
            <DropDownButton.Resources>
                <!-- Override default brushes to make the DropDownButton
                     match other command bar elements. -->
                <Style TargetType="DropDownButton">
                    <Setter Property="Height" Value="38"/>
                </Style>
                <SolidColorBrush x:Key="ButtonBackground"
                                 Color="Transparent"/>
                <SolidColorBrush x:Key="ButtonBackgroundPressed"
                                 Color="{ThemeResource SystemListMediumColor}"/>
                <SolidColorBrush x:Key="ButtonBackgroundPointerOver"
                                 Color="{ThemeResource SystemListLowColor}"/>

                <SolidColorBrush x:Key="ButtonBorderBrush"
                                 Color="Transparent"/>
                <SolidColorBrush x:Key="ButtonBorderBrushPointerOver"
                                 Color="Transparent"/>
                <SolidColorBrush x:Key="ButtonBorderBrushChecked"
                                 Color="Transparent"/>
            </DropDownButton.Resources>
            <DropDownButton.Flyout>
                <CommandBarFlyout Placement="BottomEdgeAlignedLeft">
                    <CommandBarFlyout.SecondaryCommands>
                        <AppBarButton Icon="MailReply" Label="Reply"/>
                        <AppBarButton Icon="MailReplyAll" Label="Reply all"/>
                        <AppBarButton Icon="MailForward" Label="Forward"/>
                    </CommandBarFlyout.SecondaryCommands>
                </CommandBarFlyout>
            </DropDownButton.Flyout>
        </DropDownButton>
    </AppBarElementContainer>
    <AppBarButton Icon="Placeholder"/>
    <AppBarButton Icon="Placeholder"/>
</CommandBarFlyout>

下面是命令栏浮出控件中的下拉菜单。

A command bar flyout with as a drop down button menu

用于文本控件的命令栏浮出控件

TextCommandBarFlyout 是专用的命令栏浮出控件,其中包含用于编辑文本的命令。 每个文本控件会自动将 TextCommandBarFlyout 显示为上下文菜单(右键单击),或者会在文本处于选中状态时显示它。 文本命令栏浮出控件会根据文本选择情况进行调整,仅显示相关命令。

下面是文本选择上的文本命令栏浮出控件。

A collapsed text command bar flyout

下面是显示辅助命令的扩展文本命令栏浮出控件。

An expanded text command bar flyout

可用命令

下表介绍了包含在 TextCommandBarFlyout 中的命令,以及这些命令何时显示。

命令 在以下情况下显示...
粗体 当文本控件不是只读时(仅 RichEditBox)。
斜体 当文本控件不是只读时(仅 RichEditBox)。
下划线 当文本控件不是只读时(仅 RichEditBox)。
校对 当 IsSpellCheckEnabled 为 true 且拼写错误的文本处于选中状态时。
剪切 当文本控件不是只读且文本处于选中状态时。
复制 当文本处于选中状态时。
粘贴 当文本控件不是只读且剪贴板有内容时。
撤消 当存在可以撤消的操作时。
全选 当文本可以选择时。

自定义文本命令栏浮出控件

TextCommandBarFlyout 不能自定义,由每个文本控件自动管理。 不过,可以将默认的 TextCommandBarFlyout 替换为自定义命令。

  • 若要替换在选中文本时会显示的默认 TextCommandBarFlyout,可以创建一个自定义 CommandBarFlyout(或其他浮出控件类型)并将其分配给 SelectionFlyout 属性。 如果将 SelectionFlyout 设置为 null,则在选中文本时不显示任何命令。
  • 若要替换默认的作为上下文菜单显示的 TextCommandBarFlyout,请将自定义 CommandBarFlyout(或其他浮出控件类型)分配给文本控件上的 ContextFlyout 属性。 如果将 ContextFlyout 设置为 null,则会显示在旧版文本控件中显示的菜单浮出控件,代替 TextCommandBarFlyout。

轻型消除

轻型消除控件(如菜单、上下文菜单和其他浮出控件)会捕获瞬态 UI 内的键盘焦点和游戏板焦点,直到消除为止。 若要为此行为提供视觉提示,Xbox 上的轻型消除控件将绘制覆盖,以便使 UI 范围之外的可见性变暗。 可以使用 LightDismissOverlayMode 属性来修改此行为。 默认情况下,瞬态 UI 将在 Xbox(“自动”)上绘制轻型消除覆盖层,但不会绘制其他设备系列 。 你可选择强制覆盖始终为“On”或始终为“Off” 。

<CommandBarFlyout LightDismissOverlayMode="Off" /> >

获取示例代码