SubmenusFlyouts

Um submenu é um contêiner de light dismiss que pode mostrar uma interface do usuário arbitrária como conteúdo.A flyout is a light dismiss container that can show arbitrary UI as its content. Os submenus podem conter outros submenus ou menus de contexto para criar uma experiência aninhada.Flyouts can contain other flyouts or context menus to create a nested experience.

Menu de contexto aninhado em um submenu

Obter a biblioteca de interface do usuário do WindowsGet the Windows UI Library

Logotipo do WinUI

A Biblioteca de interface do usuário do Windows 2.2 ou posterior inclui um novo modelo para esse controle que usa cantos arredondados.Windows UI Library 2.2 or later includes a new template for this control that uses rounded corners. Para obter mais informações, confira Raio de canto.For more info, see Corner radius. WinUI é um pacote NuGet que contém novos controles e recursos de interface do usuário para aplicativos do Windows.WinUI is a NuGet package that contains new controls and UI features for Windows apps. Para obter mais informações, incluindo instruções de instalação, confira Biblioteca de interface do usuário do Windows.For more info, including installation instructions, see Windows UI Library.

APIs de plataforma: Classe FlyoutPlatform APIs: Flyout class

Esse é o controle correto?Is this the right control?

  • Não use um submenu no lugar de tooltip ou menu de contexto.Don't use a flyout instead of tooltip or context menu. Use tooltip para mostrar uma breve descrição que fica oculta depois de um determinado tempo.Use a tooltip to show a short description that hides after a specified time. Use um menu de contexto para ações contextuais relacionadas a um elemento da interface do usuário, como copiar e colar.Use a context menu for contextual actions related to a UI element, such as copy and paste.

Para ver recomendações sobre quando usar um submenu e quando usar uma caixa de diálogo (um controle semelhante), confira Caixas de diálogo e submenus.For recommendations on when to use a flyout vs. when to use a dialog (a similar control), see Dialogs and flyouts.

ExemplosExamples

XAML Controls GalleryXAML Controls Gallery
XAML controls gallery

Se você tiver o aplicativo XAML Controls Gallery instalado, clique aqui para abrir o aplicativo para ver o ContentDialog ou Flyout em ação.If you have the XAML Controls Gallery app installed, click here to open the app and see the ContentDialog or Flyout in action.

Como criar um submenuHow to create a flyout

Submenus são anexados a controles específicos.Flyouts are attached to specific controls. É possível usar a propriedade Placement para especificar onde o submenu será exibido: parte superior, esquerda, parte inferior, direita ou completo.You can use the Placement property to specify where a flyout appears: Top, Left, Bottom, Right, or Full. Se você selecionar o Modo de posicionamento completo, o aplicativo se estende o submenu e centraliza na janela do aplicativo.If you select the Full placement mode, the app stretches the flyout and centers it inside the app window. Alguns controles, como Button, fornecem uma propriedade Flyout que você pode usar para associar a um submenu ou um menu de contexto.Some controls, such as Button, provide a Flyout property that you can use to associate a flyout or context menu.

Este exemplo cria um submenu simples que exibe algum texto quando o botão é pressionado.This example creates a simple flyout that displays some text when the button is pressed.

<Button Content="Click me">
  <Button.Flyout>
     <Flyout>
        <TextBlock Text="This is a flyout!"/>
     </Flyout>
  </Button.Flyout>
</Button>

Se o controle não tem uma propriedade flyout, você pode usar a propriedade Flyoutbase anexada em vez disso.If the control doesn't have a flyout property, you can use the FlyoutBase.AttachedFlyout attached property instead. Quando você fizer isso, você também precisará chamar o método Showattachedflyout para mostrar o submenu.When you do this, you also need to call the FlyoutBase.ShowAttachedFlyout method to show the flyout.

Este exemplo adiciona um submenu simples a uma imagem.This example adds a simple flyout to an image. Quando o usuário toca na imagem, o aplicativo mostra o submenu.When the user taps the image, the app shows the flyout.

<Image Source="Assets/cliff.jpg" Width="50" Height="50"
  Margin="10" Tapped="Image_Tapped">
  <FlyoutBase.AttachedFlyout>
    <Flyout>
      <TextBlock Text="This is some text in a flyout."  />
    </Flyout>
  </FlyoutBase.AttachedFlyout>
</Image>
private void Image_Tapped(object sender, TappedRoutedEventArgs e)
{
    FlyoutBase.ShowAttachedFlyout((FrameworkElement)sender);
}

Os exemplos anteriores definiram seus submenus embutido.The previous examples defined their flyouts inline. Você pode também definir um submenu como um recurso estático e, em seguida, usá-lo com vários elementos.You can also define a flyout as a static resource and then use it with multiple elements. Este exemplo cria um submenu mais complicado que exibe uma versão maior de uma imagem quando sua miniatura é tocada.This example creates a more complicated flyout that displays a larger version of an image when its thumbnail is tapped.

<!-- Declare the shared flyout as a resource. -->
<Page.Resources>
    <Flyout x:Key="ImagePreviewFlyout" Placement="Right">
        <!-- The flyout's DataContext must be the Image Source
             of the image the flyout is attached to. -->
        <Image Source="{Binding Path=Source}"
            MaxHeight="400" MaxWidth="400" Stretch="Uniform"/>
    </Flyout>
</Page.Resources>
<!-- Assign the flyout to each element that shares it. -->
<StackPanel>
    <Image Source="Assets/cliff.jpg" Width="50" Height="50"
           Margin="10" Tapped="Image_Tapped"
           FlyoutBase.AttachedFlyout="{StaticResource ImagePreviewFlyout}"
           DataContext="{Binding RelativeSource={RelativeSource Mode=Self}}"/>
    <Image Source="Assets/grapes.jpg" Width="50" Height="50"
           Margin="10" Tapped="Image_Tapped"
           FlyoutBase.AttachedFlyout="{StaticResource ImagePreviewFlyout}"
           DataContext="{Binding RelativeSource={RelativeSource Mode=Self}}"/>
    <Image Source="Assets/rainier.jpg" Width="50" Height="50"
           Margin="10" Tapped="Image_Tapped"
           FlyoutBase.AttachedFlyout="{StaticResource ImagePreviewFlyout}"
           DataContext="{Binding RelativeSource={RelativeSource Mode=Self}}"/>
</StackPanel>
private void Image_Tapped(object sender, TappedRoutedEventArgs e)
{
    FlyoutBase.ShowAttachedFlyout((FrameworkElement)sender);
}

Dê estilo ao submenuStyle a flyout

Para estilizar um submenu, modifique o FlyoutPresenterStyle.To style a Flyout, modify its FlyoutPresenterStyle. Este exemplo mostra um parágrafo de quebra de texto e torna o bloco de texto acessível para um leitor de tela.This example shows a paragraph of wrapping text and makes the text block accessible to a screen reader.

Submenu acessível com disposição de texto

<Flyout>
  <Flyout.FlyoutPresenterStyle>
    <Style TargetType="FlyoutPresenter">
      <Setter Property="ScrollViewer.HorizontalScrollMode"
          Value="Disabled"/>
      <Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Disabled"/>
      <Setter Property="IsTabStop" Value="True"/>
      <Setter Property="TabNavigation" Value="Cycle"/>
    </Style>
  </Flyout.FlyoutPresenterStyle>
  <TextBlock Style="{StaticResource BodyTextBlockStyle}" Text="Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat."/>
</Flyout>

Definição de estilo de submenus para a experiência de 3 metrosStyling flyouts for 10-foot experiences

Faça o light dismiss dos controles, como teclado de interceptação de submenu e foco de gamepad na interface do usuário transitória, até serem ignorados.Light dismiss controls like flyout trap keyboard and gamepad focus inside their transient UI until dismissed. Para fornecer uma indicação visual desse comportamento, faça light dismiss dos controles no Xbox para desenhar uma sobreposição que esmaece o contraste e a visibilidade da interface do usuário fora do escopo.To provide a visual cue for this behavior, light dismiss controls on Xbox draw an overlay that dims the contrast and visibility of out of scope UI. Esse comportamento pode ser modificado com a propriedade LightDismissOverlayMode.This behavior can be modified with the LightDismissOverlayMode property. Por padrão, os submenus desenham a sobreposição de light dismiss no Xbox, mas não em outras famílias de dispositivos. No entanto, os aplicativos podem optar por forçar a sobreposição para estar sempre Ativada ou Desativada.By default, flyouts will draw the light dismiss overlay on Xbox but not other device families, but apps can choose to force the overlay to be always On or always Off.

Submenu com sobreposição de esmaecimento

<MenuFlyout LightDismissOverlayMode="On">

Comportamento de light dismissLight dismiss behavior

Os submenus podem ser fechados com uma ação light dismiss rápida, incluindoFlyouts can be closed with a quick light dismiss action, including

  • Tocar fora do submenuTap outside the flyout
  • Pressionar a tecla Escape no tecladoPress the Escape keyboard key
  • Pressionar o botão de Voltar do sistema de hardware ou softwarePress the hardware or software system Back button
  • Pressionar o botão B do gamepadPress the gamepad B button

Ao ignorar com um toque, esse gesto é normalmente absorvido e não passado para a interface do usuário abaixo.When dismissing with a tap, this gesture is typically absorbed and not passed on to the UI underneath. Por exemplo, se houver um botão visível por trás de um submenu aberto, o primeiro toque do usuário fechará o submenu, mas não ativará esse botão.For example, if there's a button visible behind an open flyout, the user's first tap dismisses the flyout but does not activate this button. Pressionar o botão requer um segundo toque.Pressing the button requires a second tap.

É possível alterar esse comportamento ao especificar o botão como um elemento de entrada de passagem para o submenu.You can change this behavior by designating the button as an input pass-through element for the flyout. O submenu fechará como resultado da ação de light dismiss descrita acima e passará o evento de toque para o OverlayInputPassThroughElement designado.The flyout will close as a result of the light dismiss actions described above and will also pass the tap event to its designated OverlayInputPassThroughElement. Considere adotar esse comportamento para acelerar as interações do usuário em itens com funcionalidade semelhante.Consider adopting this behavior to speed up user interactions on functionally similar items. Se o aplicativo tem uma coleção de favoritos e cada item na coleção inclui um submenu anexado, é razoável esperar que os usuários queiram interagir com diversos submenus em sucessão rápida.If your app has a favorites collection and each item in the collection includes an attached flyout, it's reasonable to expect that users may want to interact with multiple flyouts in rapid succession.

[!NOTE] Tenha cuidado para não designar uma sobreposição de elemento de passagem de entrada que resulta em uma ação destrutiva.Be careful not to designate an overlay input pass-through element which results in a destructive action. Os usuários se acostumaram às ações de light dismiss rápidas que não ativam a interface do usuário principal.Users have become habituated to discreet light dismiss actions which do not activate primary UI. Fechar, Excluir ou botões destrutivos semelhantes não devem ser ativados ao fazer light dismiss rapidamente para evitar o comportamento inesperado e interrupções.Close, Delete or similarly destructive buttons should not activate on light dismiss to avoid unexpected and disruptive behavior.

No exemplo a seguir, todos os três botões dentro de FavoritesBar serão ativados no primeiro toque.In the following example, all three buttons inside FavoritesBar will be activated on the first tap.

<Page>
    <Page.Resources>
        <Flyout x:Name="TravelFlyout" x:Key="TravelFlyout"
                OverlayInputPassThroughElement="{x:Bind FavoritesBar}">
            <StackPanel>
                <HyperlinkButton Content="Washington Trails Association"/>
                <HyperlinkButton Content="Washington Cascades - Go Northwest! A Travel Guide"/>
            </StackPanel>
        </Flyout>
    </Page.Resources>

    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <StackPanel x:Name="FavoritesBar" Orientation="Horizontal">
            <HyperlinkButton x:Name="PageLinkBtn">Bing</HyperlinkButton>
            <Button x:Name="Folder1" Content="Travel" Flyout="{StaticResource TravelFlyout}"/>
            <Button x:Name="Folder2" Content="Entertainment" Click="Folder2_Click"/>
        </StackPanel>
        <ScrollViewer Grid.Row="1">
            <WebView x:Name="WebContent"/>
        </ScrollViewer>
    </Grid>
</Page>
private void Folder2_Click(object sender, RoutedEventArgs e)
{
     Flyout flyout = new Flyout();
     flyout.OverlayInputPassThroughElement = FavoritesBar;
     ...
     flyout.ShowAt(sender as FrameworkElement);
{

Obter o código de exemploGet the sample code