Popup

W oknie podręcznym zostanie wyświetlona zawartość na innych elementach interfejsu użytkownika w aplikacji. Klasa Popup w Microsoft.UI.Xaml.Controls.Primitives przestrzeni nazw jest kontenerem ogólnego przeznaczenia dla tej zawartości. Nie ma domyślnego szablonu wizualnego, dlatego udostępniasz zawartość, jej wygląd i logikę, która je otwiera i zamyka.

Popup jest blokiem konstrukcyjnym niskiego poziomu. WinUI również udostępnia kontrolki dla typowych rodzajów przejściowego interfejsu użytkownika, takich jak wysuwane menu, okna dialogowe, wskazówki kontekstowe i podpowiedzi. Te kontrolki obejmują własny styl, umieszczanie i zachowanie przy zamykaniu.

Przycisk oznaczony etykietą

Czy jest to właściwa kontrola?

Nie używaj Popup, jeśli do danego scenariusza pasuje kontrolka wyższego poziomu. Zamiast tego użyj następujących kontrolek:

Scenario Control
Pokaż informacje lub uzyskaj dane od użytkownika związane z elementem w interfejsie użytkownika, który zamyka się, gdy użytkownik kliknie poza nim. menu rozwijane
Pokaż listę poleceń lub opcji. MenuFlyout
Zadaj pytanie lub pokaż informacje, na które użytkownik musi odpowiedzieć przed kontynuowaniem. ContentDialog
Wskaż nową lub ważną funkcję ze wskazaniem konkretnego elementu lub bez niego. Etykietka nauczania
Pokaż krótki opis elementu, gdy użytkownik najecha kursorem na niego lub przenosi fokus do niego. ToolTip

Użyj Popup, jeśli potrzebujesz niestandardowej zawartości, która unosi się nad interfejsem użytkownika, a żadna z tych kontrolek nie spełnia Twoich potrzeb. Na przykład możesz użyć wyskakującego okienka dla nakładki, którą stylujesz i pozycjonujesz samodzielnie.

Wyskakujące okno nie jest modalne, więc użytkownik może nadal korzystać z interfejsu użytkownika za nim. Jeśli użytkownik musi odpowiedzieć przed kontynuowaniem, użyj elementu ContentDialog.

Zalecenia

  • Nadaj zawartości wyskakującego okna tło, obramowanie i zaokrąglone rogi, aby wyróżniała się ona na tle interfejsu użytkownika za nim. Przykład z galerii WinUI 3 używa zasobów AcrylicBackgroundFillColorDefaultBrush, SurfaceStrokeColorDefaultBrush i OverlayCornerRadius. Aby uzyskać więcej informacji, zobacz Materiał akrylowy i ThemeShadow w Popups.
  • Jeśli nie włączysz zamykania po kliknięciu poza elementem, dołącz przycisk lub inną kontrolkę, która zamyka wyskakujące okienko.
  • Treść wyskakujących okienek powinna być krótka i skupiać się na jednym zadaniu.

Utwórz wyskakujące okno

Ikona galerii WinUI 3 Aplikacja Galeria WinUI 3 zawiera interaktywne przykłady kontrolek i funkcji WinUI. Pobierz aplikację z Microsoft Store lub przejrzyj kod źródłowy w GitHub.

Wyskakujące okienko hostuje pojedynczy element, który został ustawiony jako Child. Element podrzędny jest zazwyczaj panelem lub elementem UserControl definiującym zawartość wyskakującego okna. Aby wyświetlić wyskakujące okienko, ustaw wartość IsOpen na true. Aby to ukryć, ustaw IsOpen na false.

Ten przykład jest oparty na przykładzie WinUI 3 Gallery. Deklaruje wyskakujące okno obok przycisku, który je otwiera, a zawartość wyskakującego okna zawiera przycisk zamykający wyskakujące okno.

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

Utwórz wyskakujące okienko w kodzie

Możesz również utworzyć wyskakujące okienko w kodzie bez dodawania go do drzewa wizualnego. Wyskakujące okienko zadeklarowane w języku XAML lub dodane do panelu w drzewie wizualizacji pobiera element XamlRoot z elementu nadrzędnego. Wyskakujące okienko, które nie ma elementu nadrzędnego, tak nie działa, więc przed jego otwarciem musisz ustawić jego właściwość XamlRoot.

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

Important

W systemie WinUI 3 otwarcie wyskakującego okienka, które nie ma ani elementu nadrzędnego, ani XamlRoot, kończy się niepowodzeniem. Wartość XamlRoot elementu jest null do momentu dodania elementu do aktywnego drzewa wizualnego, więc pobierz wartość z elementu, który został już załadowany, a nie w konstruktorze strony. Window W klasie można użyć polecenia this.Content.XamlRoot. Aby uzyskać więcej informacji, zobacz ContentDialog i Popup.

Note

Wyskakujące okienko, które nie znajduje się w drzewie wizualnym, nie zmienia położenia się po wyświetleniu klawiatury dotykowej, więc klawiatura może ją pokryć. Jeśli okienko podręczne zawiera kontrolki wprowadzania tekstu, takie jak TextBox, zadeklaruj wyskakujące okienko w języku XAML lub dodaj je do panelu w drzewie wizualizacji.

Zamknij wyskakujące okienko przez kliknięcie poza nim

Domyślnie wyskakujące okienko pozostaje otwarte, dopóki kod nie ustawi IsOpen na false. Ustaw wartość IsLightDismissEnabled, aby true zamknąć wyskakujące okienko, gdy użytkownik kliknie lub naciśnie poza nim albo naciśnie klawisz Esc. To zachowanie nazywa się zamykaniem po kliknięciu poza obszarem.

Domyślnie obszar poza oknem podręcznym zamykanym po kliknięciu poza nim nie jest zaciemniony. Aby ją zaciemnić, ustaw wartość LightDismissOverlayMode na On. Ta właściwość nie ma wpływu, gdy IsLightDismissEnabled ma wartość 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>

Ustaw wyskakujące okienko

Wyskakujące okienko można ustawić przy użyciu przesunięć lub względem innego elementu.

Użyj przesunięć

HorizontalOffset i VerticalOffset ustawiają położenie wyskakującego okienka w pikselach. Punkt, z którego są mierzone przesunięcia, zależy od tego, czy wyskakujące okienko ma element nadrzędny:

  • Wyskakujące okienko w drzewie wizualnym jest przesunięte z własnej pozycji w układzie elementu nadrzędnego. Na przykład w pionowym układzie StackPanel ta pozycja znajduje się poniżej elementów, które znajdują się przed wyskakującym okienkiem. W pierwszym przykładzie wyskakujące okienko współdzieli z przyciskiem pojedynczą komórkę Grid, więc pojawia się 200 pikseli na prawo od lewego górnego rogu obiektu Grid.
  • Wyskakujące okienko, które nie ma elementu nadrzędnego, na przykład takie, które tworzysz w kodzie, jest przesunięte względem lewego górnego rogu swojego głównego elementu XAML, który jest zwykle obszarem zawartości okna aplikacji.

Umieść wyskakujące okienko obok elementu

Aby wyświetlić wyskakujące okienko obok określonego elementu, ustaw parametr PlacementTarget na ten element. Następnie ustaw wartość DesiredPlacement na wartość PopupPlacementMode inną niż Auto, na przykład Bottom lub RightEdgeAlignedTop.

Po otwarciu okna podręcznego framework umieszcza je względem elementu docelowego. Jeśli okienko podręczne nie mieści się w preferowanej pozycji, framework przenosi je na przeciwną stronę obiektu docelowego. HorizontalOffset i VerticalOffset nadal mają zastosowanie i przesuwają wyskakujące okienko z obliczonej pozycji.

ActualPlacement informuje, gdzie wyświetla się wyskakujące okienko. Zdarzenie ActualPlacementChanged występuje, gdy ta wartość zmieni się, gdy wyskakujące okno jest otwarte.

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

Pokaż wyskakujące okienko poza oknem aplikacji

Domyślnie okno podręczne jest ograniczone do granic głównego elementu XAML, który jest zwykle obszarem zawartości okna aplikacji. Począwszy od Zestaw SDK do aplikacji systemu Windows 1.4, można ustawić ShouldConstrainToRootBounds na false, aby umożliwić rozszerzenie wyskakującego okienka poza okno. Na przykład możesz to zrobić, gdy wyskakujące okienko jest większe niż małe okno.

Ustaw ShouldConstrainToRootBounds przed otwarciem wyskakującego okienka po raz pierwszy. Nie można go zmienić po otwarciu wyskakującego okienka.

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

Animuj okno podręczne

Aby animować zawartość wyskakującego okna po wyświetleniu, dodaj przejście do kolekcji ChildTransitions. PopupThemeTransition udostępnia animację dla wyskakującego interfejsu użytkownika, na przykład zawartości typu etykietka narzędzia, w momencie pojawiania się.

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

Aby zamiast tego kontrolować animacjami pokazywania i ukrywania ze scenorysu, użyj poleceń PopInThemeAnimation i PopOutThemeAnimation. Aby uzyskać więcej informacji, zobacz Pokaż/ukryj wyskakujące okienko.

Reaguj po otwarciu lub zamknięciu okna podręcznego

Zdarzenie Otwarte występuje, gdy IsOpen jest ustawione na true. Zdarzenie Closed występuje, gdy IsOpen jest ustawione na false, w tym, gdy wyskakujące okienko zamyka się przez kliknięcie poza oknem. Użyj polecenia Closed w przypadku działań, które muszą zostać wykonane, niezależnie od tego, jak zamknie się okno podręczne. Na przykład przykład aplikacji WinUI 3 Gallery używa Closed w celu ponownego włączenia ustawienia, które jest wyłączone, gdy wyskakujące okienko jest otwarte.

Oba zdarzenia używają metody EventHandler<object>, więc programy obsługi przyjmują parametr object i argument zdarzenia object.

<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.";
}

Klawiatura, aktywność i ułatwienia dostępu

  • Gdy jest włączona funkcja light dismiss, otwarcie wyskakującego okienka powoduje przeniesienie fokusu do niego, a zamknięcie wyskakującego okienka powoduje zwrócenie fokusu do elementu, który miał fokus wcześniej. Użytkownik może również nacisnąć klawisz Esc, aby zamknąć okno podręczne.
  • Gdy zamykanie po kliknięciu poza nie jest włączone, wyskakujące okienko nie przenosi fokusu po otwarciu. Przenieś fokus do elementu w oknie podręcznym po jego otwarciu, dołącz przycisk Zamknij, do którego użytkownicy klawiatury mogą dotrzeć, i przywróć fokus do elementu, który otworzył okno podręczne po jego zamknięciu.
  • Wyskakujące okienko nie zgłasza zdarzeń trasowanych, takich jak KeyDown i PointerPressed. Aby obsłużyć te zdarzenia, dołącz procedury obsługi do elementu podrzędnego wyskakującego okienka.
  • Upewnij się, że każdy element interaktywny w oknie podręcznym ma dostępną nazwę. Aby uzyskać więcej informacji, zobacz Dostępność klawiatury i Uwidaczniaj podstawowe informacje o ułatwieniach dostępu.