Verwenden der UWP-XAML-Hosting-API

Von Bedeutung

In diesem Thema werden Typen aus dem Repository CommunityToolkit/Microsoft.Toolkit.Win32 GitHub verwendet oder erwähnt. Wichtige Informationen zur Unterstützung von UWP-XAML-Inseln finden Sie im XAML Islands Notice in diesem Repository.

Nicht-UWP-Desktop-Apps (einschließlich C++-Desktop (Win32), WPF und Windows Forms-Apps) können die UWP-XAML-Hosting-API verwenden, um UWP-XAML-Steuerelemente in allen UI-Elementen zu hosten, die einem Fensterhandle (HWND) zugeordnet sind. Eine Übersicht über dieses Feature finden Sie unter Hosten von UWP-XAML-Steuerelementen in Desktop-Apps (UWP-XAML-Inseln).

Ist die UWP-XAML-Hosting-API die richtige Wahl für Ihre Desktop-App?

Die UWP-XAML-Hosting-API stellt die Low-Level-Infrastruktur zum Hosten von UWP-XAML-Steuerelementen in Desktop-Apps bereit. Einige Arten von Desktop-Apps haben die Möglichkeit, alternative, komfortablere APIs zu verwenden, um dieses Ziel zu erreichen.

  • Wenn Sie über eine C++-Desktop-App verfügen und UWP-XAML-Steuerelemente in Ihrer App hosten möchten, müssen Sie die UWP-XAML-Hosting-API verwenden. Es gibt keine Alternativen für diese Arten von Apps.

  • Für WPF- und Windows Forms-Apps empfehlen wir dringend, dass Sie die steuerelemente XAML Island.NET im Windows Community Toolkit verwenden, anstatt die UWP-XAML-Hosting-API direkt zu verwenden. Diese Steuerelemente verwenden die UWP-XAML-Hosting-API intern und implementieren das gesamte Verhalten, das Sie andernfalls selbst behandeln müssen, wenn Sie die UWP-XAML-Hosting-API direkt verwendet haben, einschließlich Tastaturnavigation und Layoutänderungen.

Da nur C++-Desktop-Apps die UWP-XAML-Hosting-API verwenden, enthält dieser Artikel in erster Linie Anweisungen und Beispiele für C++-Desktop-Apps. Sie können die UWP-XAML-Hosting-API jedoch in WPF und Windows Forms Apps verwenden, wenn Sie dies auswählen. Dieser Artikel verweist auf relevanten Quellcode für die steuerelemente host für WPF und Windows Forms im Windows Community Toolkit, damit Sie sehen können, wie die UWP-XAML-Hosting-API von diesen Steuerelementen verwendet wird.

Erfahren Sie, wie Sie die XAML-Hosting-API verwenden.

Eine schrittweise Anleitung mit Codebeispielen für die Verwendung der XAML-Hosting-API in C++-Desktop-Apps finden Sie in den folgenden Artikeln:

Beispiele

Die Art und Weise, wie Sie die UWP-XAML-Hosting-API in Ihrem Code verwenden, hängt vom App-Typ, dem Entwurf Ihrer App und anderen Faktoren ab. Zur Veranschaulichung der Verwendung dieser API im Kontext einer vollständigen App bezieht sich dieser Artikel auf Code aus den folgenden Beispielen.

C++-Desktop (Win32)

Die folgenden Beispiele veranschaulichen die Verwendung der UWP-XAML-Hosting-API in einer C++-Desktop-App:

  • Simple XAML Island-Beispiel. In diesem Beispiel wird eine grundlegende Implementierung des Hostens eines UWP-XAML-Steuerelements in einer entpackten C++-Desktop-App veranschaulicht.

  • XAML Island mit benutzerdefiniertem Steuerelementbeispiel. In diesem Beispiel wird eine vollständige Implementierung des Hostings eines benutzerdefinierten UWP-XAML-Steuerelements in einer verpackten C++-Desktop-App sowie das Behandeln anderer Verhaltensweisen wie Tastatureingabe und Fokusnavigation veranschaulicht.

WPF und Windows Forms

Das steuerelement WindowsXamlHost im Windows Community Toolkit dient als Referenzbeispiel für die Verwendung der UWP-XAML-Hosting-API in WPF- und Windows Forms-Apps. Der Quellcode ist an den folgenden Speicherorten verfügbar:

Hinweis

Es wird dringend empfohlen, die steuerelemente XAML Island .NET im Windows Community Toolkit zu verwenden, anstatt die UWP-XAML-Hosting-API direkt in WPF- und Windows Forms-Apps zu verwenden. Die WPF- und Windows Forms Beispiellinks in diesem Artikel dienen nur veranschaulichenden Zwecken.

Architektur der API

Die UWP-XAML-Hosting-API enthält diese wichtigsten Windows-Runtime Typen und COM-Schnittstellen.

Typ oder Schnittstelle Description
WindowsXamlManager Diese Klasse stellt das UWP-XAML-Framework dar. Diese Klasse stellt eine einzelne statische InitializeForCurrentThread-Methode bereit, die das UWP-XAML-Framework im aktuellen Thread in der Desktop-App initialisiert.
DesktopWindowXamlSource Diese Klasse stellt eine Instanz von UWP-XAML-Inhalten dar, die Sie in Ihrer Desktop-App hosten. Das wichtigste Element dieser Klasse ist die Content-Eigenschaft . Sie weisen diese Eigenschaft einem Windows.UI.Xaml.UIElement zu, das Sie hosten möchten. Diese Klasse verfügt auch über andere Member zum Weiterleiten der Tastaturfokusnavigation in und außerhalb der XAML-Inseln.
IDesktopWindowXamlSourceNative Diese COM-Schnittstelle stellt die AttachToWindow-Methode bereit, die Sie zum Anfügen einer XAML-Insel in Ihrer App an ein übergeordnetes UI-Element verwenden. Jedes DesktopWindowXamlSource -Objekt implementiert diese Schnittstelle.
IDesktopWindowXamlSourceNative2 Diese COM-Schnittstelle stellt die PreTranslateMessage-Methode bereit, mit der das UWP-XAML-Framework bestimmte Windows-Nachrichten ordnungsgemäß verarbeiten kann. Jedes DesktopWindowXamlSource -Objekt implementiert diese Schnittstelle.

Das folgende Diagramm veranschaulicht die Hierarchie von Objekten in einer XAML-Insel, die in einer Desktop-App gehostet wird.

  • Auf der Basisebene befindet sich das UI-Element in Ihrer App, in dem Sie die XAML-Insel hosten möchten. Dieses UI-Element muss über ein Fensterhandle (HWND) verfügen. Beispiele für UI-Elemente, in denen Sie eine XAML-Insel hosten können, sind ein window für C++-Desktop-Apps, a System.Windows.Interop.HwndHost for WPF apps, and a System.Windows.Forms.Control for Windows Forms apps.

  • Auf der nächsten Ebene ist ein DesktopWindowXamlSource-Objekt vorhanden. Dieses Objekt stellt die Infrastruktur zum Hosten der XAML-Insel bereit. Ihr Code ist für das Erstellen dieses Objekts und das Anfügen dieses Objekts an das übergeordnete UI-Element verantwortlich.

  • Wenn Sie eine DesktopWindowXamlSource erstellen, erstellt dieses Objekt automatisch ein systemeigenes untergeordnetes Fenster, um Ihr UWP-XAML-Steuerelement zu hosten. Dieses systemeigene untergeordnete Fenster wird größtenteils in Ihrem Code abstrahiert, Sie können jedoch bei Bedarf auf den handle (HWND) zugreifen.

  • Schließlich ist auf oberster Ebene das UWP-XAML-Steuerelement, das Sie in Ihrer Desktop-App hosten möchten. Dies kann ein beliebiges UWP-Objekt sein, das von Windows.UI.Xaml.UIElement abgeleitet wird, einschließlich aller von Windows SDK bereitgestellten UWP-XAML-Steuerelemente sowie benutzerdefinierter Steuerelemente.

DesktopWindowXamlSource-Architektur

Hinweis

Wenn Sie UWP-XAML-Inseln in einer Desktop-App hosten, können Sie mehrere Bäume von XAML-Inhalten gleichzeitig auf demselben Thread ausführen. Verwenden Sie die Klasse XamlRoot, um auf das Stammelement einer Struktur von XAML-Inhalten in einer XAML-Insel zuzugreifen und verwandte Informationen über den Kontext abzurufen, in dem sie gehostet wird. Die CoreWindow-, ApplicationView- und Window-APIs enthalten keine korrekten Informationen für UWP-XAML-Inseln. Weitere Informationen finden Sie in diesem Abschnitt.

Bewährte Methoden

Befolgen Sie bei Verwendung der UWP-XAML-Hosting-API die folgenden bewährten Methoden für jeden Thread, der UWP-XAML-Steuerelemente hosten:

Problembehandlung

Fehler beim Verwenden der UWP-XAML-Hosting-API in einer UWP-App

Thema Beschluss
Ihre App empfängt eine COMException mit der folgenden Meldung: "DesktopWindowXamlSource kann nicht aktiviert werden. Dieser Typ kann nicht in einer UWP-App verwendet werden." oder "WindowsXamlManager kann nicht aktiviert werden. Dieser Typ kann nicht in einer UWP-App verwendet werden." Dieser Fehler gibt an, dass Sie versuchen, die UWP-XAML-Hosting-API (insbesondere die DesktopWindowXamlSource - oder WindowsXamlManager-Typen ) in einer UWP-App zu instanziieren. Die UWP-XAML-Hosting-API soll nur in Nicht-UWP-Desktop-Apps wie WPF, Windows Forms und C++-Desktopanwendungen verwendet werden.

Fehler beim Verwenden der WindowsXamlManager- oder DesktopWindowXamlSource-Typen

Thema Beschluss
Ihre App empfängt eine Ausnahme mit der folgenden Meldung: "WindowsXamlManager und DesktopWindowXamlSource werden für Apps unterstützt, die auf Windows Version 10.0.18226.0 und höher abzielen. Überprüfen Sie entweder das Anwendungsmanifest oder das Paketmanifest, und stellen Sie sicher, dass die MaxTestedVersion-Eigenschaft aktualisiert wird." Dieser Fehler gibt an, dass Ihre Anwendung versucht hat, die Typen WindowsXamlManager oder DesktopWindowXamlSourcetypen in der UWP-XAML-Hosting-API zu verwenden, aber das Betriebssystem kann nicht bestimmen, ob die App für Windows 10, Version 1903 oder höher erstellt wurde. Die UWP-XAML-Hosting-API wurde zunächst als Vorschau in einer früheren Version von Windows 10 eingeführt, wird jedoch erst ab Windows 10, Version 1903, unterstützt.

Um dieses Problem zu beheben, erstellen Sie entweder ein MSIX-Paket für die App, und führen Sie es aus dem Paket aus, oder installieren Sie das Microsoft.Toolkit.Win32.UI.SDK NuGet-Paket in Ihrem project.

Fehler beim Anfügen an ein Fenster in einem anderen Thread

Thema Beschluss
Ihre App empfängt eine COMException mit der folgenden Meldung: "Die AttachToWindow-Methode ist fehlgeschlagen, da der angegebene HWND in einem anderen Thread erstellt wurde." Dieser Fehler gibt an, dass Ihre Anwendung die IDesktopWindowXamlSourceNative::AttachToWindow-Methode aufgerufen und den HWND eines Fensters übergeben hat, das in einem anderen Thread erstellt wurde. Sie müssen dieser Methode das HWND eines Fensters übergeben, das im selben Thread erstellt wurde wie der Code, von dem aus Sie die Methode aufrufen.

Fehler beim Anfügen an ein Fenster in einem anderen Fenster auf oberster Ebene

Thema Beschluss
Ihre App empfängt eine COMException mit der folgenden Meldung: "Die AttachToWindow-Methode ist fehlgeschlagen, da der angegebene HWND von einem anderen Fenster der obersten Ebene absteigt als der HWND, der zuvor an AttachToWindow im selben Thread übergeben wurde." Dieser Fehler gibt an, dass Ihre Anwendung die IDesktopWindowXamlSourceNative::AttachToWindow-Methode aufgerufen hat und sie an den HWND eines Fensters übergeben hat, das von einem anderen Fenster auf oberster Ebene abweicht als ein Fenster, das Sie in einem vorherigen Aufruf dieser Methode im selben Thread angegeben haben.

Nachdem Ihre Anwendung "AttachToWindow" für einen bestimmten Thread aufgerufen hat, können alle anderen DesktopWindowXamlSource-Objekte im selben Thread nur an Fenster angefügt werden, die untergeordnete Elemente desselben Fensters der obersten Ebene sind, das im ersten Aufruf von AttachToWindow übergeben wurde. Wenn alle DesktopWindowXamlSource-Objekte für einen bestimmten Thread geschlossen werden, ist die nächste DesktopWindowXamlSource dann wieder frei, an jedes Fenster anzufügen.

Um dieses Problem zu beheben, schließen Sie entweder alle DesktopWindowXamlSource-Objekte , die an andere Fenster der obersten Ebene in diesem Thread gebunden sind, oder erstellen Sie einen neuen Thread für diese DesktopWindowXamlSource.