Controles flotantes

Un control flotante es un contenedor de cierre del elemento por cambio de foco que puede mostrar una interfaz de usuario arbitraria como su contenido. Los controles flotantes pueden contener otros controles flotantes o menús contextuales para crear una experiencia anidada.

¿Es este el control adecuado?

  • No uses un control flotante en lugar de una información sobre herramientas o un menú contextual. Usa una información sobre herramientas para mostrar una descripción breve que se oculta tras un tiempo determinado. Usa un menú contextual para acciones contextuales relacionadas con un elemento de la 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.

UWP y WinUI 2

Importante

La información y los ejemplos de este artículo están optimizados para aplicaciones que usan el SDK de Aplicaciones para Windows y WinUI 3, pero generalmente son aplicables a las aplicaciones para UWP que usan WinUI 2. Consulte el material de referencia de las API de UWP para obtener información y ejemplos específicos de la plataforma.

Esta sección contiene información que necesita para usar el control en una aplicación para UWP o WinUI 2.

Las API de este control existen en el espacio de nombres Windows.UI.Xaml.Controls .

Se recomienda usar la versión más reciente de WinUI 2 para obtener los estilos y plantillas más actuales para todos los controles. WinUI 2.2 o posterior incluye una nueva plantilla para este control que usa esquinas redondeadas. Para obtener más información, consulta Radio de redondeo.

Crear un control flotante

La aplicación WinUI 3 Gallery incluye ejemplos interactivos de la mayoría de los controles, las características y la funcionalidad de WinUI 3. Obtenga la aplicación en Microsoft Store o el código fuente en GitHub.

Los controles flotantes se asocian a controles específicos. Puede usar la propiedad Placement para especificar dónde aparece un control flotante: Parte superior, izquierda, abajo, derecha o completo. Si seleccionas el modo de colocación completa, la aplicación amplía el control flotante y lo centra dentro de la ventana de la 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 control flotante simple que muestra parte del 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, puedes usar la propiedad asociada FlyoutBase.AttachedFlyout. Si haces esto, también tienes que llamar al método FlyoutBase.ShowAttachedFlyout para mostrar el control flotante.

En este ejemplo se agrega un control flotante simple a una imagen. Cuando el usuario pulsa la imagen, la aplicación muestra el control flotante.

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

En los ejemplos anteriores, los controles flotantes se definen alineados. También puedes definir un control flotante como un recurso estático y después usarlo con varios elementos. En este ejemplo se crea un control flotante más complicado que muestra una versión más grande de una imagen cuando se pulsa la 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);
}

Diseñar un control flotante

Para diseñar un control flotante, modifica su propiedad FlyoutPresenterStyle. En el siguiente ejemplo se muestra un párrafo de texto ajustado y se permite 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 del elemento por cambio de foco de Xbox dibujan una superposición que atenúa el contraste y la visibilidad de la interfaz de usuario que está fuera del ámbito. Este comportamiento se puede modificar con la propiedad LightDismissOverlayMode. De manera predeterminada, los controles flotantes dibujarán la superposición de cierre del elemento por cambio de foco en Xbox pero no de otras familias de dispositivos, aunque las aplicaciones pueden elegir forzar la superposición siempre en Activado o siempre en Desactivado.

Control flotante con atenuación de superposición

<MenuFlyout LightDismissOverlayMode="On">

Comportamiento de cierre del elemento por cambio de foco

Los controles flotantes se pueden cerrar con una rápida acción de cierre del elemento por cambio de foco, incluidas:

  • 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, primera pulsación del usuario descarta el control flotante, pero no activa este botón. Al presionar el botón se requiere una segunda pulsación.

Puede cambiar este comportamiento designando el botón como elemento de paso a través de entrada para el control flotante. El control flotante se cierra como resultado de las acciones de cierre del elemento por cambio de foco descritas anteriormente y también pasará el evento de pulsación con 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 designar un elemento de paso a través de entrada de superposición que produzca una acción destructiva. Los usuarios se han habituado a acciones de cierre del elemento por cambio de foco 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);
{

Obtención del código de ejemplo