Navigationsmodell (mit C#/VB/C++ und XAML)

Das in den Projektvorlagen für Hub-Apps, Raster Apps und geteilte Apps verwendete Navigationsmodell wird für Windows Store-Apps empfohlen, die mit XAML erstellt werden. Bei diesem Modell wird ein zentraler Frame als Inhalt des Standardfensters erstellt. Anschließend navigieren die Benutzer mithilfe dieses Frames zu anderen Seiten. Das Modell für die Einzelframenavigation ermöglicht einen reibungsloseren, App-ähnlichen Übergang zwischen Seiten und erleichtert Ihnen auch das Verwalten des Programmzustands. Weitere Informationen zur Navigation und ein Beispiel zur Verwendung der integrierten Navigation in Windows Store-Apps, die mit XAML erstellt werden, finden Sie unter Schnellstart: Verwenden der Einzelseitennavigation.

Wichtig  Die Informationen in diesem Thema wurden für Microsoft Visual Studio 2013 aktualisiert.

Mithilfe der Datei "App.xaml.cs/vb/cpp" wird ein Frame erstellt (sofern noch kein Frame vorhanden ist). Zudem wird der Frame zum Inhalt des aktuellen Fensters. Wenn der Inhalt des Frames null ist, navigiert die App zur Startseite, wie im CodeBehind für App.xaml angegeben. In der Raster-App lautet der Code z. B. rootFrame.Navigate(typeof(GroupedItemsPage), "AllGroups") ).

Während des Setups registriert SuspensionManager den Frame. SuspensionManager ist eine Hilfsklasse, die im Ordner "Allgemein" der Vorlage für Raster-Apps oder geteilte Apps bereitgestellt wird. Sie enthält die Implementierung, mit deren Hilfe der Zustand beim Beenden der App gespeichert und geladen wird.

Alle Apps durchlaufen einen Anwendungslebenszyklus, der vom Betriebssystem festgelegt wird. Bei jedem Beenden einer App durch das System aufgrund von Ressourcenbeschränkungen, Abschaltungen, Neustarts usw. müssen Sie als Entwickler beim Fortsetzen der App die Daten wiederherstellen. SuspensionManager soll Sie bei dieser Aufgabe unterstützen.

SuspensionManager erfasst den globalen Sitzungszustand, um die Verwaltung der Prozesslebensdauer für eine Anwendung zu vereinfachen. Der Sitzungszustand wird unter einer Reihe von Umständen automatisch gelöscht und sollte nur zum Speichern von Informationen verwendet werden, die aus praktischen Gründen zwar sitzungsübergreifend beibehalten, jedoch bei einem Absturz oder Upgrade einer Anwendung verworfen werden sollten. Dazu zählen hauptsächlich vorübergehende UI-Daten.

SuspensionManager hat zwei Eigenschaften: SessionState und KnownTypes.

  • SessionState bietet Zugriff auf den globalen Sitzungszustand für die aktuelle Sitzung. Dieser Zustand wird mithilfe der SaveAsync-Methode serialisiert und durch die RestoreAsync-Methode wiederhergestellt. Alle Daten werden mit DataContractSerialization gespeichert und wiederhergestellt, und sie sollten möglichst kompakt sein. Die Verwendung von Zeichenfolgen oder anderen eigenständigen Datentypen wird dringend empfohlen.
  • Mit KnownTypes wird eine Liste benutzerdefinierter Typen gespeichert, die für DataContractSerializer bereitgestellt wird. DataContractSerializer wird von den SaveAsync- und RestoreAsync-Methoden beim Lesen und Schreiben des Sitzungszustands verwendet. Zur Anpassung des Serialisierungsprozesses können weitere Typen hinzugefügt werden, die anfangs leer sind.

SuspensionManager speichert den Zustand in einem Wörterbuch, SessionState. Das Wörterbuch speichert FrameState in Abhängigkeit von einem Schlüssel, der eindeutig an einen Frame gebunden ist. Jedes FrameState-Wörterbuch enthält den Zustand für die einzelnen Seiten im Navigationszustand für den jeweiligen Frame. Jede Seite speichert den Navigationsparameter sowie alle anderen Zustände, für deren Hinzufügung sich der Benutzer entscheidet.

Dies funktioniert wie folgt: wenn ein Frame erstellt wird und Sie den Zustand für diesen Frame speichern möchten, muss er umgehend registriert werden. Frames werden mithilfe des folgenden Aufrufs registriert: (SuspensionManager.RegisterFrame(rootFrame, "AppFrame")). Jedem Frame muss ein eindeutiger Schlüssel zugeordnet sein. Generell weisen die meisten Apps nur einen einzelnen Frame auf. Wenn Sie einen zweiten Frame deklarieren, muss dieser ebenfalls registriert werden. Beim Registrieren eines Frames werden zwei angefügte Eigenschaften für den Frame festgelegt. Bei der ersten Eigenschaft handelt es sich um den Schlüssel, den Sie dem Frame zugeordnet haben. Die zweite Eigenschaft ist das Wörterbuch mit dem Sitzungszustand, der dem Frame zugeordnet wird. Für zuvor registrierte Frames werden die Navigation und der Zustand sofort wiederhergestellt. Die Registrierung von Frames kann auch aufgehoben werden. Dabei werden der gesamte Navigationszustand und der gesamte Verlauf verworfen.

Kommen wir nun zu den wichtigen Aufrufen: SaveAsync und RestoreAsync. SaveAsync wird zum Speichern der gesamten SessionState-Eigenschaft verwendet. Alle per SuspensionManager.RegisterFrame registrierten Apps behalten ebenfalls den aktuellen Navigationsstapel bei, der wiederum der zugehörigen aktiven Seite das Speichern der darauf enthaltenen Daten ermöglicht. Die SessionState-Eigenschaft wird dann mit einem DataContractSerializer serialisiert und in eine Datei geschrieben, die gemäß ApplicationData-Definition im lokalen Ordner gespeichert wird.

Die RestoreAsync-Methode wird zum Lesen des zuvor gespeicherten SessionState-Objekts verwendet. Alle für RegisterFrame registrierten Apps stellen ebenfalls den vorherigen Navigationszustand wieder her, der der zugehörigen aktiven Seite das Wiederherstellen ihres Zustands ermöglicht. Auch hier wird, wie bei der SaveAsync-Methode, ein DataContractSerializer zum Deserialisieren des Zustands verwendet, der in einer Datei im lokalen Ordner der Anwendung gespeichert ist.

Es gibt zwei häufige Fehler, die beim Speicherversuch des App-Zustands durch den Benutzer auftreten können.

  • Die von den einzelnen Seiten gespeicherten Typen müssen vom DataContractSerializer in C# und VB serialisiert werden können. Dazu muss ein beliebiger benutzerdefinierter Typ registriert werden, bevor eine Speicherung oder Wiederherstellung möglich ist. SuspensionManager enthält die KnownTypes-Auflistung, mit deren Hilfe die Typen in der Auflistung an den DataContractSerializer übergeben werden. Beim SuspensionManager-Aufruf zum Wiederherstellen des Zustands in der OnLaunched-Überschreibung des CodeBehind für App.xaml eignet sich der App-Konstruktor besonders gut zum Registrieren der Typen.

            public App()
            {
                this.InitializeComponent();
                this.Suspending += OnSuspending;
                SuspensionManager.KnownTypes.Add(typeof(MyCustomType));
            }
    
  • Die bei der Verwendung der Navigation übergebenen Parameter müssen von der Plattform serialisiert werden können. Beim Speichern und Wiederherstellen des Navigationsstapels rufen wir Frame.GetNavigationState() und Frame.SetNavigationState() auf. Für beide dieser Aufrufe wird ein internes Serialisierungsformat verwendet, und alle als Parameter in Frame.Navigate() übergebenen Typen müssen von der Plattform serialisiert werden können.

Die Verwendung von SuspensionManager wird in die Implementierung von NavigationHelper eingeschlossen.

NavigationHelper ist eine Implementierung einer Seite, die die folgenden bedeutenden Annehmlichkeiten bietet:

  • Ereignishandler für GoBack, GoForward und GoHome.
  • Maus und Tastenkombinationen für die Navigation.
  • Zustandsverwaltung für die Navigation und Verwaltung der Prozesslebensdauer.

Standardansichtsmodell

Das DefaultViewModel-Element wird von allen komplexen Seitenelementvorlagen verwendet. Das DataContext-Element ist an das DefaultViewModel-Element gebunden, das auf der Seite selbst definiert ist: DataContext="{Binding DefaultViewModel, RelativeSource={RelativeSource Self}}". Die DefaultViewModel-Eigenschaft hat den Typ ObservableDictionary, wobei es sich um eine Zuordnung der Zeichenfolgen (Schlüssel) zu den Objekten (Werten) handelt. Das DefaultViewModel-Element wird der Einfachheit halber bereitgestellt und kann bei Bedarf in ein stark typisiertes Ansichtsmodell geändert werden.

Anschließend werden die einzelnen Seiten an Eigenschaften gebunden, die im CodeBehind für das DefaultViewModel festgelegt werden sollen. Sehen wir uns beispielsweise das GroupedItemsPage-Objekt an. Auf dieser Seite ist die Source-Eigenschaft für CollectionViewSource an die Groups-Eigenschaft gebunden (Source="{Binding Groups}". Die Groups-Eigenschaft ist ein Schlüssel eines Schlüssel/Wert-Paars, das im DefaultViewModel gespeichert ist (this.DefaultViewModel["Groups"] = sampleDataGroups;).

Zuordnung der Anwendungsansicht zum visuellen Zustand

In den Vorlagen unter Windows 8 wurde vom LayoutAwarePage-Element Code zum Behandeln des Ansichtszustands bereitgestellt, aber dieser Code ist unter Windows 8.1 nicht erforderlich. Nur die Seiten SplitPage und FileOpenPicker enthalten Code zum Behandeln des Ansichtszustands. Es wird jetzt für alle Seiten erwartet, dass sie alle Fenstergrößen behandeln können, bei denen die Breite mindestens 500px beträgt.

Mit NavigationHelper werden Befehle für GoBack und GoForward registriert. Mithilfe dieser Implementierungen wird überprüft, ob der Seite ein Frame zugeordnet ist und, falls dies der Fall ist, ob der Frame vor dem Aufrufen von Frame.GoBack() oder Frame.GoForward() vor- oder zurückwechseln kann. Dies kann außer Kraft gesetzt werden, um das Standardverhalten zu ändern, z. B. für die geteilte Seite (Split Page).

NavigationHelper dient zudem der Registrierung der allgemeinen Mausbewegungen und Tastenkombinationen, die normalerweise zum Navigieren verwendet werden. Die Maus-Zurück-Taste, ALT + NACH-LINKS-TASTE und die ZURÜCK-Taste auf der Tastatur werden zum Zurücknavigieren verwendet. Die Maus-Vorwärts-Taste, ALT + NACH-RECHTS-TASTE und die VORWÄRTS-Taste auf der Tastatur werden zum Vorwärtsnavigieren verwendet.

Prozessverwaltung für Lebensdauer

Zusätzlich zur Bereitstellung der oben beschriebenen Implementierungen muss NavigationHelper auch von den Ereignishandlern OnNavigatedTo() und OnNavigatedFrom() aufgerufen werden, die auf den einzelnen Seiten implementiert sind. Wenn diese Ereignisse auftreten, wird von NavigationHelper eine seitenspezifische Implementierung von LoadState() und SaveState() aufgerufen. Sie können die Implementierung dieser Funktionen auf jeder Seite anpassen. Sie sollten anstelle von OnNavigatedTo() bzw. OnNavigatedFrom() verwendet werden.

OnNavigatedFrom() wird aufgerufen, wenn die Seite in einem Frame angezeigt werden soll. Beim Navigieren zu einer neuen Seite wird der mit der Seite verknüpfte Zustand geladen. Beim Wiederherstellen der Seite wird der zuvor gespeicherte Zustand der Seite wiederhergestellt. Anschließend wird die LoadState-Methode aufgerufen, sodass die einzelnen Seiten reagieren können. LoadState umfasst zwei Parameter – den ursprünglichen Navigationsparameter, der an OnNavigatedTo übergeben wird, und den vorherigen Seitenzustand (sofern er vorhanden ist).

OnNavigatedFrom() wird aufgerufen, wenn die Seite nicht mehr in einem Frame angezeigt werden soll. Durch das Wegnavigieren von einer Seite ermöglichen wir der Seite das Speichern des aktuellen Zustands. Es leeres Wörterbuch wird an SaveState() übergeben. Die einzelnen Seiten können SaveState überschreiben und Objekte im Wörterbuch mit Schlüssel überschreiben (Zeichenfolge in Objekt). Dieses Wörterbuch wird anschließend der Seite zugeordnet und dem SessionState-Objekt hinzugefügt, das von SuspensionManager für den jeweiligen Frame überwacht wird.

Hinweis  

  • Alle auf der individuellen Seite gespeicherten Daten müssen für die Serialisierung mit dem DataContractSerializer verfügbar sein. Weitere Informationen finden Sie in der Erläuterung für den SuspensionManager zu Beginn dieses Themas.
  • Zudem ist es wichtig, dass an dieser Stelle nur vorübergehende UI-Informationen gespeichert werden, weil dieser Zustand beim Schließen auf andere Art und Weise als mit der Terminated-Methode verloren geht.

Struktur einer App

Um die Struktur einer App zu erklären, verwenden wir eine mit der Projektvorlage "Grid App" erstellte App. Den Ausgangspunkt für alle XAML-basierten Windows Store-Apps bilden das Anwendungsobjekt in App.xaml und der zugehörige CodeBehind. Der erste Code, der beim Erstellen der App ausgeführt wird, ist der App-Konstruktor. Danach wird eine der zahlreichen Aktivierungsmethoden aufgerufen. In diesem Fall ist es das OnLaunched-Ereignis, wenn die App über eine Kachel auf dem Startbildschirm gestartet wird. Bei diesem Aufruf wird ein Frame erstellt. Zudem werden vorherige Zustände neu geladen (wenn die App zuvor beendet wurde), und der Rahmen wird dann zum Navigieren zur ersten Seite verwendet. Beim Navigieren zu einer Seite wird vom OnNavigatedTo-Ereignishandler auf der Seite das NavigationHelper-Element aufgerufen. Das NavigationHelper-Element wird ausgeführt. Dieses Objekt zeichnet zudem die Parameter auf, und es lädt die vorherigen Zustandsinformationen für die jeweilige Seite neu. Anschließend wird die LoadState()-Methode aufgerufen, die im GroupedItemsPage-Objekt überschrieben wird. Hier werden Daten geladen, und das Standardansichtsmodell wird ausgefüllt. Beim Navigieren auf eine andere Seite wird vom OnNavigatedFrom-Ereignishandler das NavigationHelper-Element aufgerufen, mit dem alle Zustände für diese Seite per Aufruf von SaveState() gespeichert werden. SaveState() wird auf Seiten mit einem vorübergehenden UI-Zustand (beispielsweise das SplitPage-Objekt) überschrieben, bevor die Navigation zu der neuen Seite erfolgt und dann erneut Aufrufe bis zur LoadState()-Methode erfolgen.

Verwandte Themen

C#-, VB- und C++-Projektvorlagen für Windows Store-Apps

Teil 2: Verwalten von App-Lebenszyklus und -Zustand

Teil 3: Navigation, Layout und Ansichten