Pop-up

Um pop-up exibe conteúdo sobre a outra interface do usuário em seu aplicativo. A classe Pop-up no Microsoft.UI.Xaml.Controls.Primitives namespace é um contêiner de uso geral para esse conteúdo. Ele não tem modelo visual padrão, portanto, você fornece o conteúdo, sua aparência e a lógica que o abre e fecha.

Popup é um bloco de construção de baixo nível. O WinUI também fornece controles para tipos comuns de interface do usuário transitória, como menus suspensos, caixas de diálogo, dicas de ensino e dicas de ferramentas. Esses controles incluem seu próprio estilo, posicionamento e comportamento de fechamento.

Um botão rotulado

Esse é o controle correto?

Não use um Popup se um controle de nível superior se ajustar ao seu cenário. Use os controles abaixo:

Scenario Controle
Mostrar informações ou receber entrada do usuário relacionadas a um item, em uma interface do usuário que se fecha quando o usuário clica fora dela. Flyout
Mostrar uma lista de comandos ou opções. MenuFlyout
Faça uma pergunta ou mostre informações às quais o usuário deve responder antes de continuar. ContentDialog
Aponte um recurso novo ou importante, com ou sem direcionar um elemento específico. Dica de Ensino
Mostre uma breve descrição de um elemento quando o usuário passa o mouse sobre ele ou move o foco para ele. Tooltip

Use um Popup quando precisar de conteúdo personalizado que flutue acima da interface do usuário e nenhum desses controles atenda às suas necessidades. Por exemplo, você pode usar um pop-up para uma sobreposição que você mesmo estiliza e posiciona.

Um pop-up não é modal, portanto, o usuário ainda pode interagir com a interface do usuário por trás dele. Se o usuário precisar responder antes de continuar, use um ContentDialog.

Recommendations

  • Dê ao conteúdo pop-up um plano de fundo, uma borda e cantos arredondados para que ele se destaque da interface do usuário por trás dele. O exemplo da Galeria do WinUI 3 usa os recursos OverlayCornerRadius, AcrylicBackgroundFillColorDefaultBrush e SurfaceStrokeColorDefaultBrush. Para obter mais informações, consulte material acrílico e ThemeShadow em pop-ups.
  • Se você não habilitar light dismiss, inclua um botão ou outro controle que feche o pop-up.
  • Mantenha o conteúdo pop-up breve e focado em uma única tarefa.

Criar um pop-up

Ícone da Galeria do WinUI 3 O aplicativo Da Galeria do WinUI 3 inclui exemplos interativos de controles e recursos do WinUI. Obtenha o aplicativo na Microsoft Store ou navegue pelo código-fonte em GitHub.

Um pop-up hospeda um único elemento, que você define como seu Child. O filho geralmente é um painel ou um UserControl que define o conteúdo pop-up. Para mostrar o pop-up, defina IsOpen como true. Para ocultá-lo, defina IsOpen como false.

Este exemplo é baseado no exemplo da Galeria do WinUI 3. Ele declara um pop-up ao lado do botão que o abre e o conteúdo pop-up inclui um botão que fecha o pop-up.

<Grid HorizontalAlignment="Left" VerticalAlignment="Top">
    <Button Content="Show popup" Click="ShowPopupClicked" />
    <Popup x:Name="StandardPopup" HorizontalOffset="200" VerticalOffset="0">
        <Grid MinWidth="240"
              Padding="16"
              Background="{ThemeResource AcrylicBackgroundFillColorDefaultBrush}"
              BorderBrush="{ThemeResource SurfaceStrokeColorDefaultBrush}"
              BorderThickness="1"
              CornerRadius="{StaticResource OverlayCornerRadius}">
            <StackPanel Spacing="8">
                <TextBlock FontSize="16" Text="Simple popup" />
                <Button Content="Close" Click="ClosePopupClicked" />
            </StackPanel>
        </Grid>
    </Popup>
</Grid>
// Opens the popup if it isn't already open.
private void ShowPopupClicked(object sender, RoutedEventArgs e)
{
    if (!StandardPopup.IsOpen)
    {
        StandardPopup.IsOpen = true;
    }
}

// Closes the popup when the user clicks the Close button inside it.
private void ClosePopupClicked(object sender, RoutedEventArgs e)
{
    if (StandardPopup.IsOpen)
    {
        StandardPopup.IsOpen = false;
    }
}

Criar um pop-up no código

Você também pode criar um pop-up no código sem adicioná-lo à árvore visual. Um pop-up que você declara em XAML ou adiciona a um painel na árvore visual obtém seu XamlRoot de seu elemento pai. Um pop-up sem pai não tem pai, portanto, você deve definir sua propriedade XamlRoot antes de abri-la.

private Popup? _popup;

private void ShowPopupFromCodeClicked(object sender, RoutedEventArgs e)
{
    _popup ??= new Popup
    {
        // PopupContent is a UserControl in your app that defines the popup content.
        Child = new PopupContent(),
        IsLightDismissEnabled = true,

        // Required because this popup isn't in the visual tree. Use the XamlRoot
        // of an element that's already loaded, such as the button that was clicked.
        XamlRoot = ((UIElement)sender).XamlRoot
    };

    _popup.IsOpen = true;
}

Importante

No WinUI 3, a abertura de um pop-up que não tem nem um elemento pai nem XamlRoot falha. O XamlRoot de um elemento é null até que o elemento seja adicionado à árvore visual ativa, portanto, obtenha o valor de um elemento que já está carregado, em vez de em um construtor de página. Em uma Window classe, você pode usar this.Content.XamlRoot. Para obter mais informações, consulte ContentDialog e Pop-up.

Note

Um pop-up que não está na árvore visual não se reposiciona quando o teclado virtual é exibido, portanto, o teclado pode cobri-lo. Se o pop-up contiver controles de entrada de texto, como um TextBox, declare o pop-up em XAML ou adicione-o a um painel na árvore visual.

Fechar um pop-up com dispensa leve

Por padrão, um pop-up permanece aberto até que seu código defina IsOpen como false. Defina IsLightDismissEnabled para true fechar o pop-up quando o usuário clicar ou tocar fora dele ou pressionar a tecla Esc. Esse comportamento é chamado de light dismiss.

Por padrão, a área fora de um pop-up com descarte ao clicar fora não está escurecida. Para escurecer, defina LightDismissOverlayMode como On. Essa propriedade não tem efeito quando IsLightDismissEnabled é false.

<Popup x:Name="LightDismissPopup"
       IsLightDismissEnabled="True"
       LightDismissOverlayMode="On">
    <Border Padding="16"
            Background="{ThemeResource AcrylicBackgroundFillColorDefaultBrush}"
            BorderBrush="{ThemeResource SurfaceStrokeColorDefaultBrush}"
            BorderThickness="1"
            CornerRadius="{StaticResource OverlayCornerRadius}">
        <TextBlock Text="Click outside this popup or press Esc to close it." />
    </Border>
</Popup>

Posicionar um pop-up

Você pode posicionar um pop-up usando deslocamentos ou em relação a outro elemento.

Usar deslocamentos

HorizontalOffset e VerticalOffset definem a posição do pop-up, em pixels. O ponto a partir do qual os deslocamentos são medidos depende de se o pop-up tem um pai:

  • Um pop-up na árvore visual é deslocado de sua própria posição no layout de seu elemento pai. Por exemplo, em uma vertical StackPanel, essa posição está abaixo dos elementos que vêm antes do pop-up. No primeiro exemplo, o pop-up compartilha uma única célula Grid com o botão, portanto, ele aparece 200 pixels à direita do canto superior esquerdo do Grid.
  • Um pop-up que não tem pai, como um que você cria no código, tem um deslocamento em relação ao canto superior esquerdo da raiz XAML, que geralmente é a área de conteúdo da janela do aplicativo.

Colocar um pop-up ao lado de um elemento

Para mostrar um pop-up ao lado de um elemento específico, defina PlacementTarget para esse elemento. Em seguida, defina DesiredPlacement como um valor de PopupPlacementMode diferente de Auto, como Bottom ou RightEdgeAlignedTop.

Quando o pop-up é aberto, o framework o posiciona em relação ao elemento de destino. Se o pop-up não se ajustar à posição preferencial, o framework o moverá para o lado oposto do alvo. HorizontalOffset e VerticalOffset ainda se aplicam e deslocam o pop-up da posição calculada.

ActualPlacement indica onde o pop-up é mostrado. O evento ActualPlacementChanged ocorre quando esse valor é alterado enquanto o pop-up está aberto.

<StackPanel Spacing="8">
    <Button x:Name="DetailsButton" Content="Show details" Click="ShowDetailsClicked" />
    <TextBlock x:Name="PlacementStatus" />
    <Popup x:Name="DetailsPopup"
           PlacementTarget="{x:Bind DetailsButton}"
           DesiredPlacement="BottomEdgeAlignedLeft"
           IsLightDismissEnabled="True"
           ActualPlacementChanged="DetailsPopup_ActualPlacementChanged">
        <Border Padding="16"
                Background="{ThemeResource AcrylicBackgroundFillColorDefaultBrush}"
                BorderBrush="{ThemeResource SurfaceStrokeColorDefaultBrush}"
                BorderThickness="1"
                CornerRadius="{StaticResource OverlayCornerRadius}">
            <TextBlock Text="This popup appears below the button when there's room." />
        </Border>
    </Popup>
</StackPanel>
private void ShowDetailsClicked(object sender, RoutedEventArgs e)
{
    DetailsPopup.IsOpen = true;
}

private void DetailsPopup_ActualPlacementChanged(object sender, object e)
{
    // ActualPlacement differs from DesiredPlacement when the popup
    // doesn't fit in the preferred position.
    PlacementStatus.Text = $"Actual placement: {DetailsPopup.ActualPlacement}";
}

Mostrar um pop-up fora da janela do aplicativo

Por padrão, um pop-up é restrito aos limites de sua raiz XAML, que geralmente é a área de conteúdo da janela do aplicativo. A partir do SDK do Aplicativo Windows 1.4, você pode definir ShouldConstrainToRootBounds para false e permitir que o pop-up se estenda além da janela. Por exemplo, você pode fazer isso quando o pop-up for maior que uma janela pequena.

Defina ShouldConstrainToRootBounds antes de abrir o pop-up pela primeira vez. Não é possível alterá-lo depois que o pop-up for aberto.

<Popup x:Name="UnconstrainedPopup" ShouldConstrainToRootBounds="False">
    <!-- Popup content -->
</Popup>

Animar um pop-up

Para animar o conteúdo pop-up quando ele aparecer, adicione uma transição à coleção ChildTransitions . PopupThemeTransition fornece a animação para a interface do usuário pop-in, como conteúdo semelhante à dica de ferramenta, à medida que aparece.

<Popup x:Name="AnimatedPopup" IsLightDismissEnabled="True">
    <Popup.ChildTransitions>
        <TransitionCollection>
            <PopupThemeTransition />
        </TransitionCollection>
    </Popup.ChildTransitions>
    <Border Padding="16"
            Background="{ThemeResource AcrylicBackgroundFillColorDefaultBrush}"
            BorderBrush="{ThemeResource SurfaceStrokeColorDefaultBrush}"
            BorderThickness="1"
            CornerRadius="{StaticResource OverlayCornerRadius}">
        <TextBlock Text="This content animates when the popup opens." />
    </Border>
</Popup>

Para controlar as animações de mostrar e ocultar de um storyboard, use PopInThemeAnimation e PopOutThemeAnimation. Para obter mais informações, consulte Mostrar/ocultar pop-up.

Responder quando um pop-up é aberto ou fechado

O evento Aberto ocorre quando IsOpen é definido como true. O evento Closed ocorre quando IsOpen é definido como false, inclusive quando o pop-up é fechado ao clicar fora dele. Use Closed para tarefas que precisam ocorrer independentemente de como o pop-up seja fechado. Por exemplo, o exemplo da Galeria do WinUI 3 usa Closed para habilitar novamente uma configuração que ele desabilita enquanto o pop-up está aberto.

Ambos os eventos usam EventHandler<object>, para que os manipuladores peguem um object remetente e um object argumento de evento.

<StackPanel Spacing="8">
    <TextBlock x:Name="StatusText" />
    <Popup x:Name="StatusPopup"
           IsLightDismissEnabled="True"
           Opened="StatusPopup_Opened"
           Closed="StatusPopup_Closed">
        <!-- Popup content -->
    </Popup>
</StackPanel>
private void StatusPopup_Opened(object sender, object e)
{
    StatusText.Text = "The popup is open.";
}

private void StatusPopup_Closed(object sender, object e)
{
    // Closed occurs for every close, including light dismiss.
    StatusText.Text = "The popup is closed.";
}

Teclado, foco e acessibilidade

  • Quando a dispensa ao clicar fora está habilitada, abrir o pop-up move o foco para ele e fechar o pop-up retorna o foco para o elemento que tinha foco antes. O usuário também pode pressionar Esc para fechar o pop-up.
  • Quando light dismiss não está habilitado, o pop-up não move o foco quando é aberto. Mova o foco para um elemento no pop-up depois de abri-lo, inclua um botão Fechar que os usuários de teclado podem acessar e retorne o foco para o elemento que abriu o pop-up após o fechamento.
  • Um pop-up não gera eventos roteados, como KeyDown e PointerPressed. Para lidar com esses eventos, anexe os manipuladores ao elemento filho do pop-up.
  • Verifique se cada elemento interativo no pop-up tem um nome acessível. Para obter mais informações, consulte Acessibilidade do teclado e expor informações básicas de acessibilidade.