Compartir a través de


Flyouts

Un flyout es un contenedor que se cierra con un clic fuera de él y puede mostrar una interfaz de usuario arbitraria como su contenido. Los flyouts pueden contener otros flyouts o menús contextuales para crear una experiencia de navegación anidada.

¿Es este el control adecuado?

  • No utilice un control flotante en lugar de sugerencia de herramienta o el menú contextual. Utiliza la función de información sobre herramientas para mostrar una breve descripción que se oculta después de un tiempo especificado. Use un menú contextual para acciones contextuales relacionadas con un elemento de interfaz de usuario, como copiar y pegar.

Para obtener recomendaciones sobre cuándo usar un control flotante frente a cuándo se debe usar un cuadro de diálogo (un control similar), vea Cuadros de diálogo y controles flotantes.

Crear un menú desplegable

Icono de la galería de WinUI 3 La aplicación Galería de WinUI 3 incluye ejemplos interactivos de características y controles winUI. Obtenga la aplicación del Microsoft Store o examine el código fuente en GitHub.

Los menús desplegables están adjuntos a controles específicos. Puede usar la propiedad Placement para especificar dónde aparece un desplegable: superior, izquierda, inferior, derecha o completo. Si selecciona el modo de colocación completa, la aplicación amplía el desplegable y lo centra dentro de la ventana de la propia aplicación. Algunos controles, como Botón, proporcionan una propiedad Control flotante que puede usar para asociar un control flotante o un menú contextual.

En este ejemplo se crea un flyout simple que muestra un texto cuando se presiona el botón.

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

Si el control no tiene una propiedad flyout, puede usar en su lugar la propiedad adjunta FlyoutBase.AttachedFlyout. Al hacerlo, también necesita invocar el método FlyoutBase.ShowAttachedFlyout para mostrar el control flotante.

En este ejemplo se añade un menú desplegable simple a una imagen. Cuando el usuario pulsa la imagen, la aplicación muestra el menú desplegable.

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

Los ejemplos anteriores definieron sus menús desplegables en línea. También puede definir un menú desplegable como un recurso estático y, a continuación, usarlo con varios elementos. En este ejemplo se crea un desplegable más complejo que muestra una versión más grande de una imagen cuando se toca su miniatura.

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

Estilizar un menú desplegable

Para aplicar estilo a un Flyout, modifique su FlyoutPresenterStyle. En este ejemplo se muestra un párrafo de ajuste de texto y se hace que el bloque de texto sea accesible para un lector de pantalla.

Control flotante accesible con texto ajustado

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

Dar estilo a controles flotantes para las experiencias de 10 pies

Los controles de cierre del elemento por cambio de foco como los controles flotantes capturan el foco del teclado y del controlador para juegos dentro de su interfaz de usuario transitoria hasta que se cierra. Para proporcionar una indicación visual para este comportamiento, los controles de cierre con luz en Xbox muestran una superposición que atenúa el contraste y la visibilidad de la interfaz de usuario fuera de su ámbito. Este comportamiento se puede modificar con la propiedad LightDismissOverlayMode. De forma predeterminada, los controles flotantes mostrarán la superposición para descartar suavemente en Xbox, pero no en otras familias de dispositivos; sin embargo, las aplicaciones pueden optar por forzar que la superposición esté siempre Activada o siempre Off.

Desplegable con superposición atenuada

<MenuFlyout LightDismissOverlayMode="On">

Comportamiento de cierre ligero

Los controles flotantes se pueden cerrar con una rápida acción de desestimación, incluida:

  • Pulsar fuera del control flotante.
  • Presionar la tecla de teclado Escape.
  • Presionar el botón Atrás del sistema de hardware o software.
  • Presionar el botón B del controlador para juegos.

Al descartar con una pulsación, este gesto se absorbe normalmente y no pasa a la interfaz de usuario que se encuentra debajo. Por ejemplo, si hay un botón visible detrás de un control flotante abierto, la primera pulsación del usuario cierra el control flotante, pero no activa el botón. Al presionar el botón se requiere una segunda pulsación.

Puede cambiar este comportamiento designando el botón como un elemento de paso de entrada para el menú desplegable. El elemento emergente se cerrará como resultado de las acciones de cierre descritas anteriormente al perder el foco y también pasará el evento de toque a su OverlayInputPassThroughElement designado. Considere adoptar este comportamiento para acelerar las interacciones del usuario en elementos funcionalmente similares. Si su aplicación tiene una colección de favoritos y cada elemento de la colección incluye un control flotante adjunto, resulta razonable esperar que los usuarios puedan querer interactuar con varios controles flotantes en una sucesión rápida.

Nota:

Tenga cuidado de no seleccionar un elemento de paso de entrada superpuesto que pueda causar una acción destructiva. Los usuarios se han acostumbrado a acciones de cierre discretas que no activan la interfaz de usuario principal. Los botones Cerrar, Eliminar o similarmente destructivos no deben activarse al descartar la luz para evitar comportamientos inesperados y perjudiciales.

En el siguiente ejemplo, se activarán los tres botones dentro de la FavoritesBar con la primera pulsación.

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