菜单弹出和菜单栏

菜单弹出窗口用于菜单和上下文菜单场景中,以便在用户请求时显示一组命令或选项。 菜单弹出框显示一个可以包含菜单项和子菜单的单一顶级菜单。 要在水平行中显示一组多个顶级菜单,请使用菜单栏(通常位于应用窗口顶部)。

典型上下文菜单的示例

这是正确的控制吗?

请参阅菜单和上下文菜单以帮助识别菜单与上下文菜单的场景,以及关于何时使用菜单悬浮窗与命令栏悬浮窗的指南。

菜单弹出窗口可以用作普通菜单和上下文菜单,以组织命令。 要显示任意内容(如通知或请求确认),则使用对话框或弹出项目。

如果需要经常使用某一特定命令并希望有可用的空间,请参阅集合命令获取有关该命令直接置于自己的元素中的示例,以便用户无需遍历菜单即可访问它。

创建菜单弹出框

WinUI 3 示例集图标 WinUI 3 示例库应用包含 WinUI 控件和功能的交互式示例。 从 Microsoft Store 或浏览 GitHub 上的源代码获取应用。

要创建菜单弹出项目,请使用 MenuFlyout 类。 通过将 MenuFlyoutItem、MenuFlyoutSubItem、SplitMenuFlyoutItem、ToggleMenuFlyoutItem、RadioMenuFlyoutItem 和 MenuFlyoutSeparator 对象添加到 MenuFlyout,可以定义菜单的内容。

这些对象用于:

此示例将创建 MenuFlyout,并使用 ContextFlyout 属性(该属性适用于大多数控件),以显示 MenuFlyout 作为上下文菜单。

<Rectangle
  Height="100" Width="100">
  <Rectangle.ContextFlyout>
    <MenuFlyout>
      <MenuFlyoutItem Text="Change color" Click="ChangeColorItem_Click" />
    </MenuFlyout>
  </Rectangle.ContextFlyout>
  <Rectangle.Fill>
    <SolidColorBrush x:Name="rectangleFill" Color="Red" />
  </Rectangle.Fill>
</Rectangle>
private void ChangeColorItem_Click(object sender, RoutedEventArgs e)
{
    // Change the color from red to blue or blue to red.
    if (rectangleFill.Color == Microsoft.UI.Colors.Red)
    {
        rectangleFill.Color = Microsoft.UI.Colors.Blue;
    }
    else
    {
        rectangleFill.Color = Microsoft.UI.Colors.Red;
    }
}

下一个示例几乎完全相同,但该示例使用 FlyoutBase.ShowAttachedFlyout 属性将其显示为菜单,而不是使用 ContextFlyout 属性来显示 MenuFlyout 类作为上下文菜单。

<Rectangle
  Height="100" Width="100"
  Tapped="Rectangle_Tapped">
  <FlyoutBase.AttachedFlyout>
    <MenuFlyout>
      <MenuFlyoutItem Text="Change color" Click="ChangeColorItem_Click" />
    </MenuFlyout>
  </FlyoutBase.AttachedFlyout>
  <Rectangle.Fill>
    <SolidColorBrush x:Name="rectangleFill" Color="Red" />
  </Rectangle.Fill>
</Rectangle>
private void Rectangle_Tapped(object sender, TappedRoutedEventArgs e)
{
    FlyoutBase.ShowAttachedFlyout((FrameworkElement)sender);
}

private void ChangeColorItem_Click(object sender, RoutedEventArgs e)
{
    // Change the color from red to blue or blue to red.
    if (rectangleFill.Color == Microsoft.UI.Colors.Red)
    {
        rectangleFill.Color = Microsoft.UI.Colors.Blue;
    }
    else
    {
        rectangleFill.Color = Microsoft.UI.Colors.Red;
    }
}

添加拆分按钮菜单项

WinUI 3 示例集图标 WinUI 3 示例库应用包含 WinUI 控件和功能的交互式示例。 从 Microsoft Store 或浏览 GitHub 上的源代码获取应用。

SplitMenuFlyoutItem 在菜单浮出控件中提供拆分按钮体验。 它有两个部分:

  • 主部件执行默认操作,如 MenuFlyoutItem。 若要在用户选择它时做出响应,请处理 Click 事件或设置 Command 属性。
  • 辅助部分将打开相关选项的子菜单,例如 MenuFlyoutSubItem。

当命令具有常见的默认操作和一些变体(例如以不同格式保存文件)时,请使用拆分菜单项。 这样可使菜单比将每个变体单独列为一项更简短。

注释

SplitMenuFlyoutItem 需要Windows 应用 SDK 1.8.6 或更高版本。

此示例来自 WinUI 3 库应用,将两个拆分菜单项添加到 MenuFlyout。 子菜单项位于 Items 属性中。 由于 Items 是 SplitMenuFlyoutItem 的 XAML 内容属性,因此可以直接在 SplitMenuFlyoutItem 元素中添加子菜单项。

<StackPanel Orientation="Horizontal" Spacing="12">
    <Button Content="File Options">
        <Button.Flyout>
            <MenuFlyout>
                <SplitMenuFlyoutItem Text="Save" Click="SplitMenuFlyoutItem_Click">
                    <SplitMenuFlyoutItem.Icon>
                        <FontIcon Glyph="&#xE74E;" />
                    </SplitMenuFlyoutItem.Icon>
                    <MenuFlyoutItem Text="Save as .docx" Click="SplitMenuFlyoutItem_Click" />
                    <MenuFlyoutItem Text="Save as .pdf" Click="SplitMenuFlyoutItem_Click" />
                    <MenuFlyoutItem Text="Save as .txt" Click="SplitMenuFlyoutItem_Click" />
                </SplitMenuFlyoutItem>
                <SplitMenuFlyoutItem Text="Share" Icon="Share" Click="SplitMenuFlyoutItem_Click">
                    <MenuFlyoutItem Text="Share via email" Click="SplitMenuFlyoutItem_Click" />
                    <MenuFlyoutItem Text="Share via link" Click="SplitMenuFlyoutItem_Click" />
                </SplitMenuFlyoutItem>
            </MenuFlyout>
        </Button.Flyout>
    </Button>
    <TextBlock x:Name="SelectedCommandText" VerticalAlignment="Center" />
</StackPanel>
private void SplitMenuFlyoutItem_Click(object sender, RoutedEventArgs e)
{
    // SplitMenuFlyoutItem derives from MenuFlyoutItem, so one handler works for both.
    if (sender is MenuFlyoutItem selectedItem)
    {
        SelectedCommandText.Text = "Clicked: " + selectedItem.Text;
    }
}

子菜单还可以包含 MenuFlyoutSeparator 对象和其他 SplitMenuFlyoutItem 对象。 如果 Items 集合为空,则禁用辅助部分。

若要自定义子菜单,请将 SubMenuPresenterStyle 设置为子菜单呈现元素的样式,将 SubMenuItemStyle 设置为子菜单中各项的样式。

用户在使用键盘时分别与这两个部分进行交互:

  • 当主要部分具有焦点时,按 Enter 或空格键执行默认操作,或按向右箭头键将焦点移动到次要部分。
  • 当次要部分具有焦点时,按 Enter 键或右箭头键打开子菜单。
  • 打开子菜单时,按 Esc 或左箭头键将其关闭。

屏幕阅读器还分别宣布这两个部分。 次要部分将被读作按钮,为菜单项提供更多选项。

Icons

请考虑为菜单项提供图标:

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

对于没有标准可视化的命令可不必提供图标。 难以理解的图标无助于使用,造成视觉干扰,并妨碍用户关注重要的菜单项。

带图标的示例上下文菜单

<MenuFlyout>
  <MenuFlyoutItem Text="Share" >
    <MenuFlyoutItem.Icon>
      <FontIcon Glyph="&#xE72D;" />
    </MenuFlyoutItem.Icon>
  </MenuFlyoutItem>
  <MenuFlyoutItem Text="Copy" Icon="Copy" />
  <MenuFlyoutItem Text="Delete" Icon="Delete" />
  <MenuFlyoutSeparator />
  <MenuFlyoutItem Text="Rename" />
  <MenuFlyoutItem Text="Select" />
</MenuFlyout>

小窍门

MenuFlyoutItem 中图标的大小为 16x16 像素。 如果使用 SymbolIcon、FontIcon 或 PathIcon,图标将自动缩放到正确的大小,且不会失真。 如果使用 BitmapIcon,请确保你的图像为 16x16 像素。

轻型消除

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

<MenuFlyout LightDismissOverlayMode="Off" />

创建菜单栏

WinUI 3 示例集图标 WinUI 3 示例库应用包含 WinUI 控件和功能的交互式示例。 从 Microsoft Store 或浏览 GitHub 上的源代码获取应用。

可以使用相同的元素在菜单栏中创建菜单,就像在菜单弹出项目中一样。 但是,不是在 MenuFlyout 中对 MenuFlyoutItem 对象进行分组,而是在 MenuBarItem 元素中进行分组。 每个 MenuBarItem 都作为顶级菜单添加到 MenuBar。

菜单栏的示例

注释

此示例仅显示如何创建 UI 结构,但不显示任何命令的实现。

<MenuBar>
    <MenuBarItem Title="File">
        <MenuFlyoutSubItem Text="New">
            <MenuFlyoutItem Text="Plain Text Document"/>
            <MenuFlyoutItem Text="Rich Text Document"/>
            <MenuFlyoutItem Text="Other Formats..."/>
        </MenuFlyoutSubItem>
        <MenuFlyoutItem Text="Open..."/>
        <MenuFlyoutItem Text="Save"/>
        <MenuFlyoutSeparator />
        <MenuFlyoutItem Text="Exit"/>
    </MenuBarItem>

    <MenuBarItem Title="Edit">
        <MenuFlyoutItem Text="Undo"/>
        <MenuFlyoutItem Text="Cut"/>
        <MenuFlyoutItem Text="Copy"/>
        <MenuFlyoutItem Text="Paste"/>
    </MenuBarItem>

    <MenuBarItem Title="View">
        <MenuFlyoutItem Text="Output"/>
        <MenuFlyoutSeparator/>
        <RadioMenuFlyoutItem Text="Landscape" GroupName="OrientationGroup"/>
        <RadioMenuFlyoutItem Text="Portrait" GroupName="OrientationGroup" IsChecked="True"/>
        <MenuFlyoutSeparator/>
        <RadioMenuFlyoutItem Text="Small icons" GroupName="SizeGroup"/>
        <RadioMenuFlyoutItem Text="Medium icons" IsChecked="True" GroupName="SizeGroup"/>
        <RadioMenuFlyoutItem Text="Large icons" GroupName="SizeGroup"/>
    </MenuBarItem>

    <MenuBarItem Title="Help">
        <MenuFlyoutItem Text="About"/>
    </MenuBarItem>
</MenuBar>