Freigeben über


Verwalten von App-Fenstern

Die Windows App SDK stellt die Klasse Microsoft.UI.Windowing.AppWindow bereit, die eine allgemeine Abstraktion des HWND darstellt. Es gibt eine 1 : 1-Zuordnung zwischen einem und einem HWND der obersten Ebene in der App. 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 APIs in Ihrer App veranschaulicht. Als Voraussetzung wird empfohlen, die informationen zu AppWindow in Windowing-Übersicht für WinUI 3 und Windows App SDK zu lesen und zu verstehen. Dies gilt, unabhängig davon, ob Sie WinUI oder ein anderes Benutzeroberflächenframework verwenden.

  • Wichtige APIs: Klasse, OverlappedPresenter-Klasse

Öffnen Sie die WinUI 3 Gallery-App, und sehen Sie sie in Aktion.

WinUI 3-Galeriesymbol Die WinUI 3 Gallery-App enthält interaktive Beispiele für WinUI-Steuerelemente und -Features. Rufen Sie die App aus dem Microsoft Store ab, oder durchsuchen Sie den Quellcode auf GitHub.

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

In der Regel verwenden Sie 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 -Änderungen

Sie reagieren auf Änderungen am , 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 .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();
    }
}

Größe und Platzierung

Die 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 , sodass Sie die . -Eigenschaft verwenden können, um die 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 PageKlasse, sodass Sie nicht automatisch über access an die Objekte oder verfügen. Sie haben einige Optionen, um die zu erhalten.

  • Wenn Sie einen Verweis auf gemäß der Beschreibung in Nachverfolgen des aktuellen Fensters oder Nachverfolgen von -Instanzen verwalten, können Sie und dann aus der Eigenschaft . abrufen.
  • Oder Sie können die statische Methode .GetFromWindowId aufrufen, um die Instanz abzurufen, wie hier gezeigt. (Siehe Ermitteln des Fensters, in dem ein visuelles Element gehostet wird.)
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 ist ein AppWindowPresenter (Präsentator) zugewiesen. Das System erstellt einen Präsentator, der zum Zeitpunkt der Erstellung auf ein 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 oder geändert werden. Sie können auch .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 Objekts angewendet wird, ist eine Instanz von OverlappedPresenter mit den Standardeinstellungen der Eigenschaften. Es ist nicht erforderlich, einen Verweis darauf beizubehalten, 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 beibehält, für den er erstellt wurde; und Sie können ihn erneut anwenden, indem Sie die .SetPresenter-Methode mit AppWindowPresenterKind.Default als Parameter aufrufen.

Von Bedeutung

Durch Aufrufen von wird die mit 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 *-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
IstMinimierbar 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 .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 () aufrufen. Ein overlappedPresenter kann keine Titelleiste ohne Rahmen haben. Das heißt, wenn der Parameter lautet , muss der Parameter auch sein . Andernfalls wird eine Ausnahme mit dieser Meldung ausgelöst:

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

Setzen Sie IsMaximizable auf , um die Schaltfläche "Maximieren" in der Symbolleiste auszublenden. Es wird empfohlen, dies zu tun, wenn Sie die 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 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 die Größenänderungssteuerelemente auszublenden und zu verhindern, dass der Benutzer die Größe des Fensters ändert. Dies wirkt sich nicht auf Aufrufe der .Resize-Methode aus.

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

Legen Sie "PreferredMaximumHeight " und " PreferredMaximumWidth " fest, um die maximale Größe einzuschränken, auf die der Benutzer das Fenster strecken kann. Wir empfehlen, auf 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 .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 .Resize; die Fenstergröße wird nicht kleiner als die festgelegte Mindesthöhe und Mindestbreite geändert.

Sie können IsModal so festlegen, dass 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 Seite in der WinUI 3 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 .Presenter-Eigenschaft ändert sich), wird Ihre App über ein .Changed-Ereignis für das betroffene benachrichtigt, wobei die Eigenschaft AppWindowChangedEventArgs.DidPresenterChange auf 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 angewendet werden kann.

In diesem Beispiel wird gezeigt, wie man Folgendes tut:

  • Verwenden Sie die . Presenter-Eigenschaft zum Abrufen des aktuellen Referenten.
  • Verwenden Sie die AppWindowPresenter.Kind-Eigenschaft , um zu überprüfen, welche Art von Konfiguration derzeit angewendet wird.
  • Verwenden Sie .SetPresenter, um die aktuelle Konfiguration zu ändern.

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 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 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) weiterhin den Einstiegspunkt dieses Frameworks zum Erstellen eines Fensters verwenden und dessen Inhalt anfügen können. Nachdem Sie ein Fenster mit diesem Benutzeroberflächenframework erstellt haben, können Sie die in der Windows App SDK bereitgestellten Fensterinteroperabilitätsfunktionen verwenden, um auf die entsprechenden AppWindow und die zugehörigen Methoden, Eigenschaften und Ereignisse zuzugreifen.

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

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

Erhalten Sie das AppWindow für Versionen des Windows App SDK vor 1.3 (oder andere Desktop-App-Frameworks)

Die Eigenschaft Window.AppWindow 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 Fensterinteropfunktionen werden als Methoden der klasse Microsoft.UI.Win32Interop implementiert. Siehe auch Interop-APIs aus 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 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 .GetFromWindowId-Methode, um abzurufen.
// MainWindow.xaml.cs
private void myButton_Click(object sender, RoutedEventArgs e)
{
    // Retrieve the window handle (HWND) of the current (XAML) WinUI 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 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 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 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 die Arbeit mit finden Sie im Windowing-Katalogbeispiel.

Einschränkungen

Die Windows App SDK stellt derzeit keine Methoden zum Anfügen von UI-Framework-Inhalten an eine AppWindow bereit.