Anzeigen mehrerer Ansichten für eine App

Drahtmodell, das eine App mit mehreren Fenstern zeigt

Du kannst deinen Benutzern zu mehr Produktivität verhelfen, indem du ihnen ermöglichst, unabhängige Teile der App in separaten Fenstern anzuzeigen. Wenn du für eine App mehrere Fenster erstellst, verhält sich jedes Fenster anders. Benutzer können App-Fenster unabhängig voneinander verschieben, ändern, anzeigen und ausblenden und zwischen App-Fenstern wechseln, als wären sie separate Apps.

Wichtige APIs: Windows.UI.ViewManagement-Namespace, Windows.UI.WindowManagement-Namespace

Wann sollte eine App mehrere Ansichten verwenden?

Es gibt eine Reihe von Szenarien, die von mehreren Ansichten profitieren können. Hier sind einige Beispiele:

  • Eine E-Mail-App, die Benutzern beim Verfassen einer neuen E-Mail eine Liste der empfangenen Nachrichten anzeigt
  • Eine Adressbuch-App, mit der Benutzer Kontaktinformationen für mehrere Personen nebeneinander vergleichen können
  • Eine Musikplayer-App, mit der Benutzer beim Durchsuchen einer Liste anderer verfügbarer Musiktitel sehen können, was wiedergegeben wird
  • Eine Notizen-App, mit der Benutzer Informationen von einer Seite in eine andere kopieren können
  • Eine Lese-App, mit der Benutzer mehrere Artikel zur späteren Lektüre öffnen können, nachdem sie die Gelegenheit hatten, alle wichtigen Schlagzeilen durchzulesen

Während jedes App-Layout einzigartig ist, empfehlen wir dir, eine Schaltfläche für ein „Neues Fenster” an geeigneter Stelle zu platzieren, wie etwa in der rechten oberen Ecke des Inhalts, der in einem neuen Fenster geöffnet werden kann. Erwäge außerdem, die Kontextmenüoption In einem neuen Fenster öffnen einzufügen.

Weitere Informationen zum Erstellen separaten Instanzen deiner App (anstelle separater Fenster für dieselbe Instanz) findest du unter Erstellen einer Windows-App mit mehreren Instanzen.

Hosts für Windowing

Es gibt verschiedene Möglichkeiten, wie Windows-Inhalte in einer App gehostet werden können.

  • CoreWindow/ApplicationView

    Eine App-Ansicht ist die 1:1-Kopplung eines Threads und eines Fensters, das von der App zum Anzeigen von Inhalten verwendet wird. Die erste Ansicht, die beim Starten der App erstellt wird, wird als Hauptansicht bezeichnet. Jede CoreWindow/ApplicationView-Instanz agiert in einem eigenen Thread. Wenn du an verschiedenen Benutzeroberflächenthreads arbeiten musst, kann dies Anwendungen mit mehreren Fenstern komplizierter machen.

    Die Hauptansicht deiner App wird stets in ApplicationView gehostet. Inhalt in einem sekundären Fenster kann in ApplicationView oder AppWindow gehostet werden.

    Informationen zum Verwenden von ApplicationView zum Anzeigen sekundärer Fenster in deiner App findest du unter Verwenden von ApplicationView.

  • AppWindow

    AppWindow vereinfacht die Erstellung von Windows-Apps mit mehreren Fenstern, da sie auf demselben UI-Thread ausgeführt wird, aus dem sie erstellt wird.

    Die AppWindow-Klasse und andere APIs im Namespace WindowManagement sind ab Windows 10 Version 1903 (SDK 18362) verfügbar. Wenn deine App auf frühere Versionen von Windows 10 ausgerichtet ist, musst du sekundäre Fenster mithilfe von ApplicationView erstellen.

    Informationen zum Verwenden von AppWindow zum Anzeigen sekundärer Fenster in deiner App findest du unter Verwenden von AppWindow.

    Hinweis

    AppWindow ist derzeit in der Vorschauphase. Du kannst daher Apps, die AppWindow verwenden, an den Store übermitteln. Es ist jedoch von einigen Plattform- und Frameworkkomponenten bekannt, dass sie nicht mit AppWindow funktionieren (siehe Einschränkungen).

  • DesktopWindowXamlSource (XAML Islands)

    UWP-XAML-Inhalte in einer Win32-Anwendung ( unter Verwendung von HWND), auch als XAML Islands bekannt, werden in DesktopWindowXamlSource gehostet.

    Weitere Informationen zu XAML Islands findest du unter Verwenden der UWP-XAML-Hosting-API in einer Desktopanwendung.

Code als zwischen Hosts für Windowing portierbar gestalten

Wenn XAML-Inhalt in CoreWindow angezeigt wird, gibt es immer eine zugehörige ApplicationView und ein XAML Window. Du kannst APIs für diese Klassen verwenden, um Informationen wie beispielsweise die Fensterbegrenzungen abzurufen. Verwende zum Abrufen einer Instanz dieser Klassen die statische CoreWindow.GetForCurrentThread-Methode, die ApplicationView.GetForCurrentView-Methode oder die Window.Current-Eigenschaft. Darüber hinaus gibt es viele Klassen, die das GetForCurrentView-Muster verwenden, um eine Instanz der Klasse abzurufen, wie z. B. DisplayInformation.GetForCurrentView.

Diese APIs funktionieren, da es nur eine einzige Struktur von XAML-Inhalten für eine CoreWindow/ApplicationView gibt, sodass der XAML-Code den Kontext kennt, in dem es gehostet wird, dass CoreWindow/ApplicationView ist.

Wenn XAML-Inhalt innerhalb von AppWindow oder DesktopWindowXamlSource ausgeführt wird, kann es mehrere Strukturen von XAML-Inhalt geben, die gleichzeitig im selben Thread ausgeführt werden. In diesem Fall geben diese APIs nicht die richtigen Informationen, da der Inhalt nicht mehr innerhalb des aktuellen CoreWindow/ApplicationView (und XAML-Fensters) ausgeführt wird.

Um sicherzustellen, dass dein Code bei allen Hosts für Windowing ordnungsgemäß funktioniert, solltest du APIs, die auf CoreWindow, ApplicationView und Window aufsetzen, durch neue APIs ersetzen, die ihren Kontext aus der XamlRoot-Klasse beziehen. Die XamlRoot-Klasse stellt eine Struktur von XAML-Inhalten und Informationen zum Kontext dar, in dem sie gehostet wird, unabhängig davon, ob es sich um eine CoreWindow-, AppWindow- oder DesktopWindowXamlSource handelt. Mithilfe dieser Abstraktionsschicht kannst du den gleichen Code unabhängig davon schreiben, in welchem Host für Windowing der XAML-Code ausgeführt wird.

Diese Tabelle zeigt Code, der bei Hosts für Windowing nicht einwandfrei funktioniert, und den neuen portierbaren Code, durch den du ihn ersetzen kannst, sowie einige APIs, die du nicht ändern musst.

Vorher Nachher
CoreWindow.GetForCurrentThread().Bounds uiElement.XamlRoot.Size
CoreWindow.GetForCurrentThread().SizeChanged uiElement.XamlRoot.Changed
CoreWindow.Visible uiElement.XamlRoot.IsHostVisible
CoreWindow.VisibilityChanged uiElement.XamlRoot.Changed
CoreWindow.GetForCurrentThread().GetKeyState Unverändert. Wird in AppWindow and DesktopWindowXamlSource unterstützt.
CoreWindow.GetForCurrentThread().GetAsyncKeyState Unverändert. Wird in AppWindow and DesktopWindowXamlSource unterstützt.
Window.Current Gibt das zentrale Window-Objekt von XAML zurück, das eng an das aktuelle CoreWindow gebunden ist. Siehe den Hinweis unter dieser Tabelle.
Window.Current.Bounds uiElement.XamlRoot.Size
Window.Current.Content UIElement root = uiElement.XamlRoot.Content
Window.Current.Compositor Unverändert. Wird in AppWindow and DesktopWindowXamlSource unterstützt.
VisualTreeHelper.FindElementsInHostCoordinates
Der UIElement-Parameter ist zwar optional, die Methode löst aber eine Ausnahme aus, wenn ein auf einem Island gehostetes UIElement nicht angegeben wird.
Geben Sie die uiElement.XamlRoot als UIElement an, anstatt es leer zu lassen.
VisualTreeHelper.GetOpenPopups
In XAML Islands-Apps führt dies zu einem Fehler. In AppWindow-Apps führt dies zu geöffneten Popups im Hauptfenster.
VisualTreeHelper.GetOpenPopupsForXamlRoot(uiElement.XamlRoot)
FocusManager.GetFocusedElement FocusManager.GetFocusedElement(uiElement.XamlRoot)
contentDialog.ShowAsync() contentDialog.XamlRoot = uiElement.XamlRoot;
contentDialog.ShowAsync();
menuFlyout.ShowAt(null, new Point(10, 10)); menuFlyout.XamlRoot = uiElement.XamlRoot;
menuFlyout.ShowAt(null, new Point(10, 10));

Hinweis

Für XAML-Inhalte in DesktopWindowXamlSource gibt es zwar ein CoreWindow/Window im Thread, aber es ist stets unsichtbar und hat eine Größe von 1x1. Sie ist weiterhin für die App zugänglich, gibt aber keine sinnvollen Grenzen oder Sichtbarkeit zurück.

Für XAML-Inhalt in AppWindow gibt es immer genau ein CoreWindow im selben Thread. Wenn du eine GetForCurrentView- oder GetForCurrentThread-API aufrufst, gibt diese API ein Objekt zurück, das den Zustand von CoreWindow im Thread widerspiegelt, und nicht eines der AppWindows, die möglicherweise in diesem Thread ausgeführt werden.

Empfohlene und nicht empfohlene Vorgehensweisen

  • Biete einen klaren Einstiegspunkt zur sekundären Ansicht mithilfe der Glyphe „Neues Fenster öffnen” an.
  • Vermittle Benutzern den Zweck der sekundäre Ansicht.
  • Stelle sicher, dass deine App in einer Ansicht voll funktionsfähig ist und dass Benutzer nur aus praktischen Gründen eine sekundäre Ansicht öffnen.
  • Nutze die sekundäre Ansicht nicht, um Benachrichtigungen oder andere vorübergehende visuelle Elemente bereitzustellen.