Submenu da barra de comandos

O submenu da barra de comandos permite que você forneça aos usuários acesso fácil a tarefas comuns mostrando comandos em uma barra de ferramentas flutuante relacionada a um elemento em sua tela da interface do usuário.

Um submenu da barra de comandos de texto expandido

Assim como CommandBar, CommandBarFlyout tem as propriedades PrimaryCommands e SecondaryCommands que você pode usar para adicionar comandos. É possível colocar comandos em uma das coleções ou em ambas. Quando e como os comandos principais e secundários são exibidos depende do modo de exibição.

O submenu da barra de comandos tem dois modos de exibição: recolhido e expandido.

  • No modo recolhido, somente os comandos principais são mostrados. Se o submenu da barra de comandos tiver comandos primários e secundários, um botão "ver mais", que é representado por uma reticências [...], será exibido. Isso permite que o usuário tenha acesso aos comandos secundários fazendo a transição para o modo expandido.
  • No modo expandido, os comandos principais e secundários são mostrados. (Se o controle tiver apenas itens secundários, eles serão exibidos de forma semelhante ao controle MenuFlyout).

Esse é o controle correto?

Use o controle de submenu da barra de comandos para mostrar uma coleção de comandos para o usuário, como botões e itens de menu, no contexto de um elemento na tela do aplicativo.

O submenu da barra de comandos é o controle recomendado para criar menus de contexto. Isso permite que os comandos comuns (como comandos Copiar, Recortar, Colar, Excluir, Compartilhar ou seleção de texto) que são mais contextualmente relevantes para o cenário do menu de contexto sejam adicionados como comandos primários para que eles sejam mostrados como uma única linha horizontal no submenu da barra de comandos. O TextCommandBarFlyout já está configurado adequadamente para exibir automaticamente comandos de texto nos controles TextBox, TextBlock, RichEditBox, RichTextBlock e PasswordBox. Um CommandBarFlyout pode ser usado para substituir os comandos de texto padrão em controles de texto.

Para mostrar comandos contextuais em itens de lista, siga as diretrizes em Comandos contextuais para coleções e listas.

Invocação proativa versus reativa

Geralmente, há duas maneiras de invocar um submenu ou menu associado a um elemento em sua tela de interface do usuário: a invocação proativa e a invocação reativa.

Na invocação proativa, os comandos aparecem automaticamente quando o usuário interage com o item a que estão associados. Por exemplo, comandos de formatação de texto podem surgir quando o usuário seleciona o texto em uma caixa de texto. Nesse caso, o submenu da barra de comandos não entra em foco. Em vez disso, ele apresenta os comandos relevantes próximos ao item com que o usuário está interagindo. Se o usuário não interagir com os comandos, eles serão ignorados.

Na invocação reativa, os comandos são mostrados em resposta a uma ação explícita do usuário para solicitá-los, por exemplo, clicando com o botão direito do mouse. Isso corresponde ao conceito tradicional de um menu de contexto.

Você pode usar CommandBarFlyout das duas formas ou até mesmo combinando-as.

UWP e WinUI 2

Importante

As informações e exemplos neste artigo são otimizados para aplicativos que usam o SDK do Aplicativo Windows e o WinUI 3, mas geralmente são aplicáveis a aplicativos UWP que usam o WinUI 2. Consulte a referência da API da UWP para obter informações e exemplos específicos da plataforma.

Esta seção contém informações necessárias para usar o controle em um aplicativo UWP ou WinUI 2.

O controle CommandBarFlyout para aplicativos UWP está incluído como parte da Biblioteca de Interface do Usuário do Windows 2. Para obter mais informações, incluindo instruções de instalação, confira Biblioteca de interface do usuário do Windows. As APIs para esse controle existem nos namespaces Windows.UI.Xaml.Controls (UWP) e Microsoft.UI.Xaml.Controls (WinUI).

Recomendamos usar o WinUI 2 mais recente para obter os estilos e modelos mais atuais para todos os controles. O WinUI 2.2 ou posterior inclui um novo modelo para esse controle que usa cantos arredondados. Para obter mais informações, confira Raio de canto.

Para usar o código neste artigo com a WinUI 2, use um alias em XAML (usamos muxc) para representar as APIs da Biblioteca de Interface do Usuário do Windows incluídas em seu projeto. Confira Introdução à WinUI 2 para obter mais informações.

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

<muxc:CommandBarFlyout />

Criar um submenu da barra de comandos

O aplicativo Galeria da WinUI 3 inclui exemplos interativos da maioria dos controles, recursos e funcionalidades da WinUI 3. Obtenha o aplicativo na Microsoft Store ou o código-fonte no GitHub

Este exemplo mostra como criar um submenu da barra de comandos e usá-lo de forma proativa e reativa. Quando a imagem é tocada, o submenu é mostrado no modo recolhido. Quando mostrado como um menu de contexto, o submenu é mostrado no modo expandido. Em ambos os casos, o usuário pode expandir ou recolher o submenu após ele ser aberto.

<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);
}

Aqui está o submenu da barra de comandos em seu estado recolhido.

Exemplo de submenu de barra de comandos recolhido

Aqui está o mesmo submenu da barra de comandos em seu estado expandido mostrando comandos secundários.

Exemplo de submenu de barra de comandos expandido

Mostrar comandos proativamente

Quando você mostra comandos contextuais proativamente, somente os comandos principais devem ser mostrados por padrão (o submenu da barra de comandos deve estar recolhido). Coloque os comandos mais importantes na coleção de comandos principais e os comandos adicionais, que tradicionalmente iriam em um menu de contexto, na coleção de comandos secundários.

Para mostrar os comandos proativamente, você normalmente manipulará os eventos Clicar ou Tocar para exibir o submenu da barra de comandos. Defina o submenu ShowMode como ShowMode ou TransientWithDismissOnPointerMoveAway para abrir o submenu no modo recolhido sem remover o foco.

Os controles de texto têm uma propriedade SelectionFlyout . Quando você atribui um submenu a essa propriedade, ele é mostrado automaticamente quando o texto é selecionado.

Mostrar comandos reativamente

Quando você mostra comandos contextuais de reativamente, como um menu de contexto, os comandos secundários são mostrados por padrão (o submenu da barra de comandos deve ser expandido). Nesse caso, o submenu da barra de comandos pode ter comandos principais e secundários ou somente comandos secundários.

Para mostrar comandos em um menu de contexto, normalmente você atribui o submenu à propriedade ContextFlyout de um elemento de interface do usuário. Dessa forma, a abertura do submenu é manipulada pelo elemento e você não precisa fazer mais nada.

Se você manipular a exibição do submenu por conta própria (por exemplo, em um evento RightTapped), defina o submenu ShowMode como Padrão para abrir o submenu no modo expandido e colocá-lo em foco.

Dica

Para obter mais informações sobre as opções de exibição de um submenu e como controlar seu posicionamento, confira Submenus.

Mostrar um CommandBarFlyout sempre expandido

Quando você tem comandos primários e secundários em um CommandBarFlyout, o botão "veja mais" [...] é exibido por padrão e pode ser usado para expandir e recolher os comandos secundários. Se você quiser manter o CommandBarFlyout no modo expandido e mostrar os comandos secundários o tempo todo, poderá usar a CommandBarFlyout.AlwaysExpanded propriedade .

Quando a AlwaysExpanded propriedade é definida como true, o botão "ver mais" não é mostrado e o usuário não é capaz de alternar o estado expandido do controle. O CommandBarFlyout ainda será descartado normalmente quando um comando secundário for clicado ou o usuário clicar fora do submenu.

Essa propriedade só terá um efeito se o CommandBarFlyout tiver comandos secundários. Se não houver comandos secundários, o CommandBarFlyout sempre estará no modo recolhido.

Dica

Você ainda pode recolher e expandir o CommandBarFlyout programaticamente definindo a propriedade IsOpen mesmo quando a AlwaysExpanded propriedade é definida truecomo .

Comandos e conteúdo

O controle CommandBarFlyout tem duas propriedades que você pode usar para adicionar comandos e conteúdo: PrimaryCommands e SecondaryCommands.

Por padrão, os itens da barra de comandos são adicionados à coleção PrimaryCommands. Esses comandos são mostrados na barra de comandos e são visíveis nos modos recolhido e expandido. Diferente de CommandBar, comandos principais não estouram automaticamente para os comandos secundários e podem ser truncados.

Também é possível adicionar comandos à coleção SecondaryCommands. Comandos secundários são mostrados na parte do menu do controle e ficam visíveis apenas no modo expandido.

Se houver comandos comuns (como comandos Copiar, Recortar, Colar, Excluir, Compartilhar ou seleção de texto) que sejam importantes para o cenário, é recomendável adicioná-los como comandos primários em vez de comandos secundários.

Botões da barra de aplicativos

É possível popular PrimaryCommands e SecondaryCommands diretamente nos controles AppBarButton, AppBarToggleButton e AppBarSeparator.

Os controles de botão da barra de aplicativos são caracterizados por um ícone e um rótulo de texto. Esses controles são otimizados para uso em uma barra de comandos e sua aparência muda dependendo dele ser mostrado na barra de comandos ou no menu de estouro.

  • Botões da barra de aplicativos usados como comandos principais são mostrados na barra de comandos apenas com seu ícone; o rótulo de texto não é mostrado. Recomendamos que você use uma dica de ferramenta para mostrar uma descrição de texto do comando, conforme mostrado aqui.
    <AppBarButton Icon="Copy" ToolTipService.ToolTip="Copy"/>
    
  • Botões da barra de aplicativos usados como comandos secundários são mostrados no menu, com o rótulo e o ícone visíveis.

Ícones

Considere fornecer ícones de item de menu para:

  • Os itens mais usados.
  • Os itens de menu cujo ícone é bem conhecido ou padrão.
  • Os itens de menu cujo ícone ilustra bem o que faz o comando.

Não se sinta obrigado a fornecer ícones para comandos que não têm uma visualização padrão. Os ícones criptografados não são úteis, criam poluição visual e impedem que os usuários se concentrem nos itens de menu importantes.

Outros tipos de conteúdo

Você pode adicionar outros controles a um submenu da barra de comandos encapsulando-os em um AppBarElementContainer. Isso permite adicionar controles, como DropDownButton ou SplitButton, ou contêineres, como StackPanel, para criar uma interface do usuário mais complexa.

Para ser adicionado às coleções de comandos principais ou secundários de um submenu da barra de comandos, um elemento precisa implementar a interface ICommandBarElement. AppBarElementContainer é um wrapper que implementa essa interface para que você possa adicionar um elemento a uma barra de comandos mesmo que ele não implemente a interface em si.

Aqui, um AppBarElementContainer é usado para adicionar elementos extra a um submenu da barra de comandos. Um SplitButton é adicionado aos comandos principais para permitir a seleção de cores. Um StackPanel é adicionado aos comandos secundários para possibilitar um layout mais complexo para os controles de zoom.

Dica

Por padrão, elementos projetados para a tela do aplicativo podem não parecer corretos em uma barra de comandos. Quando você adiciona um elemento usando AppBarElementContainer, é necessário executar algumas etapas para fazer com que o elemento corresponda a outros elementos da barra de comandos:

  • Substitua os pincéis padrão pelo estilo leve para fazer a tela de fundo e a borda do elemento combinarem com os botões da barra de aplicativos.
  • Ajuste o tamanho e a posição do elemento.
  • Encapsule ícones em uma Viewbox com largura e altura de 16px.

Observação

Este exemplo mostra apenas a interface do usuário do submenu da barra de comandos, ele não implementa nenhum dos comandos mostrados. Para obter mais informações sobre como implementar os comandos, confira Botões e Noções básicas de design de comandos.

<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>

Aqui está o submenu da barra de comandos recolhida com um SplitButton aberto.

Um submenu da barra de comandos com um botão de divisão

Aqui está o submenu da barra de comandos expandida com a interface do usuário de zoom personalizada no menu.

Um submenu da barra de comandos com interface do usuário complexa

Criar um menu de contexto apenas com comandos secundários

Você pode usar um submenu de barra de comandos com apenas comandos secundários para criar um menu de contexto que obtenha a mesma aparência e comportamento do submenu de menu.

<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>

Aqui está o submenu da barra de comandos como um menu de contexto.

Um submenu da barra de comandos apenas com comandos secundários

Você também pode usar um CommandBarFlyout com um DropDownButton para criar um menu padrão.

<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>

Aqui está um menu de botão suspenso em um submenu da barra de comandos.

Um submenu da barra de comandos com como um botão de menu suspenso

Submenus de barra de comandos para controles de texto

O TextCommandBarFlyout é um submenu da barra de comandos especializado que contém comandos de edição de texto. Cada controle de texto mostra o TextCommandBarFlyout automaticamente como um menu de contexto (clique com o botão direito do mouse) ou quando texto é selecionado. O submenu da barra de comandos de texto se adapta à seleção de texto para mostrar apenas comandos relevantes.

Aqui está um submenu da barra de comandos de texto na seleção de texto.

Um submenu de barra de comandos de texto recolhido

Aqui está um submenu da barra de comandos de texto expandido que mostra os comandos secundários.

Um submenu da barra de comandos de texto expandido

Comandos disponíveis

Esta tabela mostra os comandos incluídos em um TextCommandBarFlyout e quando eles são mostrados.

Comando Mostrado...
Negrito quando o controle de texto não é somente leitura (RichEditBox somente).
Itálico quando o controle de texto não é somente leitura (RichEditBox somente).
Underline quando o controle de texto não é somente leitura (RichEditBox somente).
Revisão de texto quando IsSpellCheckEnabled é verdadeiro e texto digitado incorretamente é selecionado.
Recortar quando o controle de texto não é somente leitura e texto é selecionado.
Copiar quando texto é selecionado.
Colar quando o controle de texto não é somente leitura e a área de transferência tem conteúdo.
Desfazer quando há uma ação que pode ser desfeita.
Selecionar tudo quando texto pode ser selecionado.

Submenus de barra de comandos personalizados

TextCommandBarFlyout não pode ser personalizado e é gerenciado automaticamente por cada controle de texto. No entanto, você pode substituir o TextCommandBarFlyout padrão por comandos personalizados.

  • Para substituir o TextCommandBarFlyout padrão mostrado na seleção de texto, você pode criar um CommandBarFlyout personalizado (ou outro tipo de submenu) e atribuí-lo à propriedade SelectionFlyout. Se você definir SelectionFlyout como nulo, nenhum comando será mostrado na seleção.
  • Para substituir o TextCommandBarFlyout padrão mostrado como menu de contexto, atribua um CommandBarFlyout personalizado (ou outro tipo de submenu) à propriedade ContextFlyout em um controle de texto. Se você definir ContextFlyout como nulo, o submenu do menu mostrado nas versões anteriores do controle de texto será mostrado em vez do TextCommandBarFlyout.

Light dismiss

Controles light dismiss, como menus, menus de contexto e outros submenus, interceptam o foco do teclado e do gamepad dentro da interface do usuário transitória até serem ignorados. Para fornecer uma indicação visual para esse comportamento, os controles light dismiss no Xbox desenharão uma sobreposição que esmaece a visibilidade da interface do usuário fora do escopo. Esse comportamento pode ser modificado com a propriedade LightDismissOverlayMode . Por padrão, as interfaces do usuário transitórias desenham a sobreposição light dismiss no Xbox (Auto), mas não em outras famílias de dispositivos. Você pode optar por forçar que a sobreposição esteja sempre ativada ou sempre desativada.

<CommandBarFlyout LightDismissOverlayMode="Off" /> >

Obter o código de exemplo