Freigeben über


Verwalten von App-Fenstern

Das Windows App SDK stellt die Microsoft.UI.Windowing-KlasseAppWindow bereit, die eine allgemeine Abstraktion des HWND darstellt. Es gibt eine 1 : 1-Zuordnung zwischen einem AppWindow und einem HWND der obersten Ebene in der App. AppWindow und die zugehörigen Klassen stellen APIs bereit, mit denen Sie viele Aspekte der Fenster der obersten Ebene Ihrer App verwalten können, ohne direkt auf den HWND zugreifen zu müssen.

Hinweis

In diesem Artikel wird die Verwendung von AppWindow APIs in Ihrer App veranschaulicht. Als Voraussetzung wird empfohlen, die Informationen in der AppWindow zu lesen und zu verstehen, was anwendbar ist, unabhängig davon, ob Sie WinUI oder ein anderes Benutzeroberflächenframework verwenden.

Die WinUI 3 Gallery-App enthält interaktive Beispiele für die meisten WinUI 3-Steuerelemente, -Features und -Funktionen. Laden Sie die App aus dem Microsoft Store herunter, oder rufen Sie den Quellcode auf GitHub ab

Sie können APIs mit jedem ui-Framework verwenden AppWindow , das vom Windows App SDK unterstützt wird – WinUI 3, WPF, WinForms oder Win32. AppWindow APIs funktionieren zusammen mit den frameworkspezifischen Fenster-APIs:

In der Regel verwenden Sie AppWindow APIs für Folgendes:

  • Verwalten Sie die Größe und Position des App-Fensters.

  • Verwalten sie die Fenstertitel-, Symbol- und Titelleistenfarbe; oder erstellen Sie eine vollständig benutzerdefinierte Titelleiste mit AppWindowTitleBar-APIs .

    Weitere Informationen und Beispiele finden Sie in der Anpassung der Titelleiste .

  • Verwalten Sie die Darstellung und das Verhalten des Fensters mit von AppWindowPresenter abgeleiteten APIs.

Umgang mit AppWindow-Änderungen

Sie reagieren auf Änderungen am AppWindow, indem Sie das einzelne Changed-Ereignis behandeln und anschließend die Ereignisargumente (AppWindowChangedEventArgs) prüfen, um festzustellen, welche Art von Änderung aufgetreten ist. Wenn die Änderung, an der Sie interessiert sind, vorgenommen wurde, können Sie darauf reagieren. Mögliche Änderungen umfassen Position, Größe, Referenten, Sichtbarkeit und Z-Reihenfolge.

Nachfolgend finden Sie ein Beispiel für einen AppWindow.Changed-Ereignishandler.

private void AppWindow_Changed(AppWindow sender, AppWindowChangedEventArgs args)
{
    // ConfigText and SizeText are TextBox controls defined in XAML for the page.
    if (args.DidPresenterChange == true)
    {
        ConfigText.Text = sender.Presenter.Kind.ToString();
    }

    if (args.DidSizeChange == true)
    {
        SizeText.Text = sender.Size.Width.ToString() + ", " + sender.Size.Height.ToString();
    }
}

Window Größe und Platzierung

Die AppWindow Klasse verfügt über mehrere Eigenschaften und Methoden, mit deren Hilfe Sie die Größe und Platzierung des Fensters verwalten können.

Kategorie Eigenschaften
Schreibgeschützte Eigenschaften Position, Größe, ClientSize
Ereignisse Geändert (DidPositionChange, DidSizeChange)
Größen- und Positionsmethoden Move, ResizeClient, MoveAndResize
Z-Order-Methoden MoveInZOrderAtBottom, MoveInZOrderAtTop, MoveInZOrderBelow

Rufen Sie "Größe ändern" auf, um eine neue Fenstergröße anzugeben.

In diesem Beispiel befindet sich der Code in MainWindow.xaml.cs, sodass Sie die Window.AppWindow -Eigenschaft verwenden können, um die AppWindow Instanz abzurufen.

public MainWindow()
{
    InitializeComponent();
    AppWindow.Resize(new Windows.Graphics.SizeInt32(1200, 800));
}

Rufen Sie die Move-Methode auf, um die Position eines Fensters zu ändern.

In diesem Beispiel wird das Fenster so verschoben, dass es auf dem Bildschirm zentriert wird, wenn der Benutzer auf eine Schaltfläche klickt.

Dies geschieht in der Codedatei für eine Page-Klasse, sodass Sie nicht automatisch Zugriff auf die Objekte Window oder AppWindow haben. Sie haben einige Optionen, um die AppWindow zu erhalten.

private void MoveWindowButton_Click(object sender, RoutedEventArgs e)
{
    AppWindow appWindow = AppWindow.GetFromWindowId(XamlRoot.ContentIslandEnvironment.AppWindowId);
    RectInt32? area = DisplayArea.GetFromWindowId(appWindow.Id, DisplayAreaFallback.Nearest)?.WorkArea;
    if (area == null) return;
    appWindow.Move(new PointInt32((area.Value.Width - appWindow.Size.Width) / 2, (area.Value.Height - appWindow.Size.Height) / 2));
}

Die AppWindowPresenter-Klasse und Unterklassen

Jedem AppWindow ist ein AppWindowPresenter (Präsentator) zugewiesen. Das System erstellt einen Präsentator, der zum Zeitpunkt der Erstellung auf ein AppWindow angewendet wird. Jede Unterklasse von AppWindowPresenter stellt eine vordefinierte Konfiguration bereit, die für den Zweck des Fensters geeignet ist. Diese von AppWindowPresenter abgeleiteten Referenten werden bereitgestellt, und sie sind in allen unterstützten Betriebssystemversionen verfügbar.

  • CompactOverlayPresenter

    Konfiguriert ein always-on-top-Fenster mit einer festen Größe und einem Seitenverhältnis von 16:9, um Bild-im-Bild-Erlebnisse zu ermöglichen. Standardmäßig ist die InitialSizeCompactOverlaySize.Small, kann jedoch in Medium oder Large geändert werden. Sie können auch AppWindow.Resize aufrufen, um das Seitenverhältnis von 16:9 außer Kraft zu setzen und das Fenster auf eine beliebige Größe zu setzen.

  • FullScreenPresenter

    Konfiguriert ein Fenster, um eine Vollbildansicht bereitzustellen, die für das Ansehen von Videos geeignet ist. Das Fenster verfügt nicht über einen Rahmen oder eine Titelleiste und blendet die Systemaufgabenleiste aus.

  • OverlappedPresenter

    Die Standardfensterkonfiguration, die standardmäßig einen Rahmen mit Ziehpunkten zur Größenänderung und einer Titelleiste mit Schaltflächen zum Minimieren/Maximieren/Wiederherstellen bereitstellt.

Hinweis

Als neues Konzept für das Win32-Anwendungsmodell ähnelt ein Presenter einer Kombination aus Fensterzustand und Stilen, ist aber nicht identisch damit. In einigen Präsentatoren sind auch Verhaltensweisen definiert, die nicht über die klassischen Fensterstatus- und Stileigenschaften eingesehen werden können (z. B. eine automatisch ausgeblendete Titelleiste).

Der Standardpräsentator

Der Standardpräsentator, der beim Erstellen eines AppWindow Objekts angewendet wird, ist eine Instanz von OverlappedPresenter mit den Standardeinstellungen der Eigenschaften. Es ist nicht erforderlich, einen Verweis darauf zu behalten, um zum Standardpräsentator für ein Fenster zurückzukehren, nachdem ein anderer Präsentator angewendet wurde. Der Grund dafür ist, dass das System die gleiche Instanz dieses Präsentators während der gesamten Lebensdauer des AppWindow beibehält, für den er erstellt wurde; und Sie können ihn erneut anwenden, indem Sie die AppWindow.SetPresenter-Methode mit AppWindowPresenterKind.Default als Parameter aufrufen.

Von Bedeutung

Durch Aufrufen von SetPresenter(AppWindowPresenterKind.Default) wird die mit AppWindow erstellte Präsentator-Standardinstanz erneut angewendet. Wenn Sie einen anderen Präsentator erstellen und verwenden und möchten, dass er später erneut angewendet wird, müssen Sie einen Verweis auf den Präsentator beibehalten.

Sie können auch einen Verweis auf die Standard-Presenter-Instanz abrufen und ändern. Wenn Sie einen neuen Referenten angewendet haben, stellen Sie zunächst sicher, dass der Standardreferent angewendet wird, wie hier gezeigt:

appWindow.SetPresenter(AppWindowPresenterKind.Default);
OverlappedPresenter defaultPresenter = (OverlappedPresenter)appWindow.Presenter;
defaultPresenter.IsMaximizable = false;
defaultPresenter.IsMinimizable = false;

Ändern eines OverlappedPresenters

Der OverlappedPresenter ist ein flexibler Referent, den Sie auf vielfältige Weise konfigurieren können.

Mit den Create*-Methoden können Sie einen überlappenden Referenten mit Standardeigenschafteneinstellungen oder eine mit Eigenschafteneinstellungen erstellen, die für eine bestimmte Verwendung vorkonfiguriert sind.

Diese Tabelle zeigt, wie Konfigurationseigenschaften festgelegt werden, wenn Sie ein OverlappedPresenter-Objekt aus jeder Methode erstellen.

Eigentum Create CreateForContextMenu CreateForDialog CreateForToolWindow
HasBorder true true true true
HasTitleBar true false true true
IsAlwaysOnTop false false false false
IsMaximizable true false false true
IsMinimizable true false false true
IsModal false false false false
IsResizable true false false true

Der angewendete Referent ist ein Liveobjekt. Eine Änderung an einer Eigenschaft des AppWindow.Presenter-Objekts wird sofort wirksam. Es gibt keine Ereignisse, die Sie über diese Änderungen benachrichtigen, aber Sie können die Eigenschaften jederzeit auf aktuelle Werte überprüfen.

Die Eigenschaften HasBorder und HasTitleBar sind schreibgeschützt. Sie können diese Werte festlegen, indem Sie die SetBorderAndTitleBar-Methode (SetBorderAndTitleBar(bool hasBorder, bool hasTitleBar)) aufrufen. Ein overlappedPresenter kann keine Titelleiste ohne Rahmen haben. Das heißt, wenn der hasTitleBar Parameter lautet true, muss der hasBorder Parameter auch sein true. Andernfalls wird eine Ausnahme mit dieser Meldung ausgelöst:

The parameter is incorrect.
Invalid combination: Border=false, TitleBar=true.

Setzen Sie IsMaximizable auf false, um die Schaltfläche "Maximieren" in der Symbolleiste auszublenden. Es wird empfohlen, dies zu tun, wenn Sie die PreferredMaximumHeightPreferredMaximumWidth Eigenschaften festlegen, da diese Eigenschaften die Fenstergröße auch im maximierten Zustand einschränken. Dies wirkt sich nicht auf Aufrufe der Maximize-Methode aus.

Legen Sie IsMinimizable auf false fest, um die Schaltfläche „Minimieren“ in der Symbolleiste auszublenden. Dies wirkt sich nicht auf Aufrufe der Minimize-Methode aus.

Legen Sie IsResizable fest, um false die Größenänderungssteuerelemente auszublenden und zu verhindern, dass der Benutzer die Größe des Fensters ändert. Dies wirkt sich nicht auf Aufrufe der AppWindow.Resize-Methode aus.

Legen Sie IsAlwaysOnTop fest, um true dieses Fenster über anderen Fenstern zu halten. Wenn Sie eine der AppWindow.MoveInZOrder* Methoden aufrufen, werden sie weiterhin wirksam, um die Z-Reihenfolge des Fensters zu ändern, auch wenn diese Eigenschaft lautet true.

Legen Sie "PreferredMaximumHeight " und " PreferredMaximumWidth " fest, um die maximale Größe einzuschränken, auf die der Benutzer das Fenster strecken kann. Wir empfehlen, IsMaximizable auf false festzulegen, wenn Sie die maximalen Größeneigenschaften festlegen, da diese Eigenschaften die Fenstergröße auch im maximierten Zustand einschränken. Diese Eigenschaften wirken sich auch auf Aufrufe von AppWindow.Resize aus. Das Fenster wird nicht vergrößert, es wird die festgelegte maximale Höhe und Breite beibehalten.

Legen Sie "PreferredMinimumHeight " und " PreferredMinimumWidth " fest, um die Mindestgröße festzulegen, auf die der Benutzer das Fenster verkleinern kann. Diese Eigenschaften beeinflussen auch Aufrufe der Methode AppWindow.Resize; die Fenstergröße wird nicht kleiner als die festgelegte Mindesthöhe und Mindestbreite geändert.

Sie können IsModal so festlegen, dass true ein modales Fenster erstellt wird. Ein modales Fenster ist ein separates Fenster, das die Interaktion mit dem Besitzerfenster blockiert, bis es geschlossen ist. Um jedoch ein modales Fenster zu erstellen, müssen Sie auch das Besitzerfenster festlegen. andernfalls wird eine Ausnahme mit dieser Meldung ausgelöst:

The parameter is incorrect.

The window should have an owner when IsModal=true.

Zum Festlegen des Besitzerfensters in einer WinUI-App ist die Win32-Interoperabilität erforderlich. Weitere Informationen und Beispielcode finden Sie auf der AppWindow Seite in der WinUI Gallery-Beispiel-App.

Anwenden eines Präsentators

Ein Referent kann jeweils nur auf ein einzelnes Fenster angewendet werden. Wenn Sie versuchen, denselben Referenten auf ein zweites Fenster anzuwenden, wird eine Ausnahme ausgelöst. Das bedeutet, dass Sie, wenn Sie mehrere Fenster haben und die einzelnen Fenster in einen bestimmten Präsentationsmodus wechseln möchten, dann müssen Sie mehrere Referenten derselben Art erstellen und dann jedes auf ein eigenes Fenster anwenden.

Wenn ein neuer Präsentator angewendet wird (die AppWindow.Presenter-Eigenschaft ändert sich), wird Ihre App über ein AppWindow.Changed-Ereignis für das betroffene AppWindow benachrichtigt, wobei die Eigenschaft AppWindowChangedEventArgs.DidPresenterChange auf true festgelegt ist.

Tipp

Wenn Sie einen modifizierten Präsentator anwenden und den Wechsel zwischen Präsentatoren zulassen, achten Sie darauf, einen Verweis auf Ihren modifizierten Präsentator beizubehalten, damit er erneut auf AppWindow angewendet werden kann.

In diesem Beispiel wird gezeigt, wie Sie die folgenden Aktionen ausführen:

Hier wird ein Präsentator erstellt, geändert und im Konstruktor für das Fenster angewendet.

OverlappedPresenter presenter = OverlappedPresenter.Create();
presenter.PreferredMinimumWidth = 420;
presenter.PreferredMinimumHeight = 550;
AppWindow.SetPresenter(presenter);

Auf der Seite, die den Fensterinhalt darstellt, können Sie eine Referenz auf den AppWindow und den angewendeten Präsentator abrufen.

AppWindow appWindow;
OverlappedPresenter modifiedPresenter;

private void AppWindowPage_Loaded(object sender, RoutedEventArgs e)
{
    appWindow = AppWindow.GetFromWindowId(XamlRoot.ContentIslandEnvironment.AppWindowId);
    modifiedPresenter = (OverlappedPresenter)appWindow.Presenter;

    appWindow.Changed += AppWindow_Changed;
}

private void AppWindow_Changed(AppWindow sender, AppWindowChangedEventArgs args)
{
    if (args.DidPresenterChange)
    {
        // ConfigText is a TextBox control defined in XAML for the page.
        ConfigText.Text = appWindow.Presenter.Kind.ToString();
    }
}

private void CompactOverlayButton_Click(object sender, RoutedEventArgs e)
{
    if (appWindow.Presenter.Kind != AppWindowPresenterKind.CompactOverlay)
    {
        appWindow.SetPresenter(CompactOverlayPresenter.Create());
        fullScreenButton.IsChecked = false;
    }
    else
    {
        appWindow.SetPresenter(modifiedPresenter);
    }
}

private void FullScreenButton_Click(object sender, RoutedEventArgs e)
{
    if (appWindow.Presenter.Kind != AppWindowPresenterKind.FullScreen)
    {
        appWindow.SetPresenter(FullScreenPresenter.Create());
        compactOverlayButton.IsChecked = false;
    }
    else
    {
        appWindow.SetPresenter(modifiedPresenter);
    }
}

UI-Framework und HWND-Interoperabilität

Die AppWindow Klasse ist für jedes HWND auf oberster Ebene in Ihrer App verfügbar. Das bedeutet, dass Sie beim Arbeiten mit einem Desktop-UI-Framework (einschließlich WinUI 3) weiterhin den Einstiegspunkt dieses Frameworks zum Erstellen eines Fensters verwenden und dessen Inhalt anfügen können. Und nachdem Sie ein Fenster mit diesem Benutzeroberflächenframework erstellt haben, können Sie die fensterübergreifenden Funktionen (siehe unten) im Windows App SDK verwenden, um auf die entsprechenden AppWindow Methoden, Eigenschaften und Ereignisse zuzugreifen.

Einige der Vorteile der Verwendung AppWindow (auch beim Arbeiten mit einem Benutzeroberflächenframework) sind:

  • Einfache Anpassung der Titelleiste; die standardmäßig die Windows 11-Benutzeroberfläche (abgerundete Ecken, Snap Group Flyout) pflegt.
  • Systemseitige Vollbild- und kompakte Überlagerungsfunktionen (Bild in Bild).
  • Windows-Runtime (WinRT)-API-Oberfläche für einige der wichtigsten Win32-Fensterkonzepte.

Abrufen des AppWindow für Versionen des Windows App SDK vor 1.3 (oder anderen Desktop-App-Frameworks)

Die Window.AppWindow -Eigenschaft ist in Windows App SDK Version 1.3 und höher verfügbar. In früheren Versionen können Sie das funktionsäquivalente Codebeispiel in diesem Abschnitt verwenden.

C#. .NET-Wrapper für die Interoperabilitätsfunktionen für Fenster werden als Methoden der Microsoft.UI.Win32Interop-Klasse implementiert. Siehe auch Interop APIs von einer .NET-App aufrufen.

C++. Die Interopfunktionen werden in der Headerdatei winrt/Microsoft.ui.interop.h definiert.

Der folgende Codebeispielabschnitt zeigt den tatsächlichen Quellcode; hier ist jedoch das Rezept zum Abrufen eines AppWindow Objekts in einem vorhandenen Fenster:

  1. Rufen Sie den HWND für Ihr vorhandenes Fensterobjekt (für Ihr UI-Framework) ab, wenn Sie es noch nicht haben.
  2. Übergeben Sie diesen HWND an die Interoperabilitätsfunktion "GetWindowIdFromWindow ", um eine WindowId abzurufen.
  3. Übergeben Sie diese WindowId an die statische AppWindow.GetFromWindowId-Methode, um AppWindow abzurufen.
// MainWindow.xaml.cs
private void myButton_Click(object sender, RoutedEventArgs e)
{
    // Retrieve the window handle (HWND) of the current (XAML) WinUI 3 window.
    var hWnd =
        WinRT.Interop.WindowNative.GetWindowHandle(this);

    // Retrieve the WindowId that corresponds to hWnd.
    Microsoft.UI.WindowId windowId =
        Microsoft.UI.Win32Interop.GetWindowIdFromWindow(hWnd);

    // Lastly, retrieve the AppWindow for the current (XAML) WinUI 3 window.
    Microsoft.UI.Windowing.AppWindow appWindow =
        Microsoft.UI.Windowing.AppWindow.GetFromWindowId(windowId);

    if (appWindow != null)
    {
        // You now have an AppWindow object, and you can call its methods to manipulate the window.
        // As an example, let's change the title text of the window.
        appWindow.Title = "Title text updated via AppWindow!";
    }
}
// pch.h
#include "microsoft.ui.xaml.window.h" // For the IWindowNative interface.
#include <winrt/Microsoft.UI.Interop.h> // For the WindowId struct and the GetWindowIdFromWindow function.
#include <winrt/Microsoft.UI.Windowing.h> // For the AppWindow class.

// mainwindow.xaml.cpp
void MainWindow::myButton_Click(IInspectable const&, RoutedEventArgs const&)
{
    // Retrieve the window handle (HWND) of the current (XAML) WinUI 3 window.
    auto windowNative{ this->m_inner.as<::IWindowNative>() };
    HWND hWnd{ 0 };
    windowNative->get_WindowHandle(&hWnd);

    // Retrieve the WindowId that corresponds to hWnd.
    Microsoft::UI::WindowId windowId = 
        Microsoft::UI::GetWindowIdFromWindow(hWnd);

    // Lastly, retrieve the AppWindow for the current (XAML) WinUI 3 window.
    Microsoft::UI::Windowing::AppWindow appWindow = 
        Microsoft::UI::Windowing::AppWindow::GetFromWindowId(windowId);

    if (appWindow)
    {
        // You now have an AppWindow object, and you can call its methods to manipulate the window.
        // As an example, let's change the title text of the window.
        appWindow.Title(L"Title text updated via AppWindow!");
    }
}

Weitere Beispiele für das Arbeiten mit AppWindow finden Sie im Beispiel der Windowing-Galerie.

Einschränkungen

Das Windows App SDK stellt derzeit keine Methoden zum Anfügen von UI-Frameworkinhalten an ein AppWindow bereit.