Freigeben über


Übersicht über die Navigation

Windows Presentation Foundation (WPF) unterstützt die Navigation im Browserstil, die in zwei Anwendungstypen verwendet werden kann: eigenständige Anwendungen und XAML browser applications (XBAPs). Um Inhalt für die Navigation zu packen, stellt WPF die Page-Klasse bereit. Sie können deklarativ von einer Page zur anderen navigieren, entweder unter Verwendung von Hyperlink oder programmgesteuert unter Verwendung von NavigationService. WPF verwendet das Journal, um Seiten zu speichern, von denen weg navigiert wurde, und um wieder zu den Seiten zurück zu navigieren.

Page, Hyperlink, NavigationService und das Journal bilden den Kern der Navigationsunterstützung, die von WPF angeboten wird. In dieser Übersicht werden diese Features ausführlich untersucht, bevor die erweiterte Navigationsunterstützung behandelt wird, die die Navigation zu Loose Extensible Application Markup Language (XAML)-Dateien, HTML-Dateien und -Objekten umfasst.

HinweisHinweis

In diesem Thema bezieht sich der Begriff "Browser" lediglich auf Browser, die WPF-Anwendungen hosten können. Gegenwärtig zählen Microsoft Internet Explorer und Firefox zu diesen Browsern.Die Browserversion wird angegeben, wenn spezielle WPF-Features nur von einem bestimmten Browser unterstützt werden.

Dieses Thema enthält folgende Abschnitte.

  • Navigation in WPF-Anwendungen
  • Die NavigationWindow-Klasse
  • Die Frame-Klasse
  • Navigationshosts
  • Navigieren zu anderem Inhalt als XAML-Seiten
  • Sicherheit
  • Verwandte Abschnitte

In diesem Thema erhalten Sie eine Übersicht über die entscheidenden Navigationsfunktionen in WPF. Diese Funktionen sind sowohl für eigenständige Anwendungen als auch für XBAPs verfügbar, obwohl sie in diesem Thema im Kontext von XBAP vorgestellt werden.

HinweisHinweis

In diesem Thema wird das Erstellen und Bereitstellen von XBAPs nicht erläutert.Weitere Information zu XBAPs finden Sie unter Übersicht über WPF-XAML-Browseranwendungen.

In diesem Abschnitt werden die folgenden Aspekte der Navigation erklärt und veranschaulicht:

  • Implementieren einer Seite

  • Konfigurieren einer Startseite

  • Konfigurieren von Titel, Breite und Höhe des Hostfensters

  • Linknavigation

  • Fragmentnavigation

  • Navigationsdienst

  • Programmgesteuerte Navigation mit dem Navigationsdienst

  • Navigationslebensdauer

  • Aufzeichnung der Navigation mithilfe des Journals

  • Seitenlebensdauer und das Journal

  • Beibehalten des Inhaltszustands über den Navigationsverlauf

  • Cookies

  • Strukturierte Navigation

Implementieren einer Seite

In WPF können Sie zu mehreren Inhaltstypen navigieren, die .NET Framework-Objekte, benutzerdefinierte Objekte, Enumerationswerte, Benutzersteuerelemente, XAML-Dateien und HTML-Dateien umfassen. Sie werden jedoch merken, dass die Verwendung von Page die gebräuchlichste und bequemste Methode zum Packen von Inhalt ist. Außerdem implementiert Page navigationsspezifische Features, um deren Darstellung zu verbessern und die Entwicklung zu vereinfachen.

Die Verwendung von Page ermöglicht Ihnen das deklarative Implementieren einer navigierbaren Seite von XAML-Inhalt, indem Sie folgendes Markup verwenden.

<Page xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation" />

Eine in XAML implementierte Page verfügt über Page als Stammelement und erfordert die WPF XML-Namespacedeklaration. Das Page-Element enthält den Inhalt, zu dem Sie navigieren und den Sie anzeigen möchten. Sie fügen Inhalt hinzu, indem Sie das Page.Content-Eigenschaftenelement festlegen, wie im folgenden Markup gezeigt.

<Page xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation">
  <Page.Content>
    <!-- Page Content -->
    Hello, Page!
  </Page.Content>
</Page>

Page.Content kann nur ein untergeordnetes Element enthalten. Im vorherigen Beispiel besteht der Inhalt aus einer einzelnen Zeichenfolge, "Hello, Page!". In der Praxis verwenden Sie normalerweise ein Layoutsteuerelement als untergeordnetes Element (siehe Layoutsystem), um den Inhalt zu speichern und zu erstellen.

Die untergeordneten Elemente eines Page-Elements gelten als Inhalt von Page. Folglich müssen Sie die explizite Page.Content-Deklaration nicht verwenden. Das folgende Markup stellt die deklarative Entsprechung zum vorherigen Beispiel dar.

<Page xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation">
  <!-- Page Content -->
  Hello, Page!
</Page>

In diesem Fall wird Page.Content automatisch mit den untergeordneten Elementen des Page-Elements festgelegt. Weitere Informationen finden Sie unter WPF-Inhaltsmodell.

Eine Markup-Page ist hilfreich zum Anzeigen von Inhalt. Allerdings kann Page auch Steuerelemente anzeigen, mit deren Hilfe Benutzer mit der Seite interagieren. Außerdem kann die Klasse auf Benutzerinteraktionen reagieren, indem Ereignisse behandelt und Anwendungslogik aufgerufen wird. Eine interaktive Page wird durch eine Kombination aus Markup und Code-Behind implementiert, wie im folgenden Beispiel dargestellt.

<Page
    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="SDKSample.HomePage">
  Hello, from the XBAP HomePage!
</Page>

Imports System.Windows.Controls ' Page

Namespace SDKSample
    Partial Public Class HomePage
        Inherits Page
        Public Sub New()
            InitializeComponent()
        End Sub
    End Class
End Namespace
using System.Windows.Controls; // Page

namespace SDKSample
{
    public partial class HomePage : Page
    {
        public HomePage()
        {
            InitializeComponent();
        }
    }
}

Damit eine Markup- und eine Code-Behind-Datei zusammenarbeiten können, ist die folgende Konfiguration erforderlich:

  • Im Markup muss das Page-Element das x:Class-Attribut enthalten. Beim Erstellen der Anwendung führt das Vorhandensein von x:Class in der Markupdatei dazu, dass Microsoft build engine (MSBuild) eine partial-Klasse erstellt, die aus Page abgeleitet wird und den durch das x:Class-Attribut festgelegten Namen hat. Dies erfordert das Hinzufügen einer XML-Namespacedeklaration für das XAML-Schema (xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"). Die erzeugte partial-Klasse implementiert InitializeComponent, die zum Registrieren der Ereignisse und Festlegen der im Markup implementierten Eigenschaften aufgerufen wird.

  • Bei Code-Behind muss die Klasse eine partial-Klasse mit demselben Namen sein, der im Markup durch das x:Class-Attribut angegeben ist, und sie muss von Page abgeleitet werden. Auf diese Weise kann die Code-Behind-Datei mit der partial-Klasse verknüpft werden, die beim Erstellen der Anwendung (siehe Erstellen einer WPF-Anwendung (WPF)) für die Markupdatei generiert wird.

  • Bei Code-Behind muss die Page-Klasse einen Konstruktor implementieren, der die InitializeComponent-Methode aufruft. InitializeComponent wird durch die generierte partial-Klasse der Markupdatei implementiert, um Ereignisse zu registrieren und im Markup definierte Eigenschaften festzulegen.

HinweisHinweis

Wenn Sie Ihrem Projekt eine neue Page mithilfe von Microsoft Visual Studio hinzufügen, wird Page unter Verwendung von Markup und Code-Behind implementiert. Außerdem wird die Konfiguration eingefügt, die zum Erstellen der Verknüpfung zwischen Markup- und Code-Behind-Dateien, wie hier beschrieben, benötigt wird.

Wenn Page vorhanden ist, können Sie dorthin navigieren. Um die erste Page anzugeben, zu der eine Anwendung navigiert, müssen Sie die Start-Page konfigurieren.

Konfigurieren einer Startseite

XBAPs erfordern einen gewissen Umfang an Anwendungsinfrastruktur, um in einem Browser gehostet zu werden. In WPF ist die Application-Klasse Teil einer Anwendungsdefinition, die die erforderliche Anwendungsinfrastruktur (siehe Übersicht über die Anwendungsverwaltung) festlegt.

Eine Anwendungsdefinition wird normalerweise mithilfe von Markup und CodeBehind implementiert. Dabei wird die Markupdatei als ein MSBuild-ApplicationDefinition-Element konfiguriert. Das folgende Beispiel ist eine Anwendungsdefinition für eine XBAP.

<Application
    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="SDKSample.App" />

Imports System.Windows ' Application

Namespace SDKSample
    Partial Public Class App
        Inherits Application
    End Class
End Namespace
using System.Windows; // Application

namespace SDKSample
{
    public partial class App : Application { }
}

Eine XBAP kann die Anwendungsdefinition zum Angeben einer Start-Page verwenden. Diese entspricht der Page, die beim Start von XBAP automatisch geladen wird. Zu diesem Zweck legen Sie die StartupUri-Eigenschaft mit dem uniform resource identifier (URI) für die gewünschte Page fest.

HinweisHinweis

In den meisten Fällen wird Page entweder in eine Anwendung kompiliert oder mit einer Anwendung bereitgestellt.In diesen Fällen handelt es sich beim URI, der eine Page identifiziert um einen Paket-URI. Dieser wiederum entspricht einem URI, der mit dem Paket-Schema übereinstimmt.Paket-URIs werden unter Paket-URI in WPF ausführlicher erläutert. Sie können auch mit dem HTTP-Schema zum Inhalt navigieren. Das Schema wird nachfolgend erklärt.

Sie können StartupUri deklarativ in Markup festlegen, wie im folgenden Beispiel veranschaulicht.

<Application
    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="SDKSample.App"
    StartupUri="PageWithHyperlink.xaml" />

In diesem Beispiel wird das StartupUri-Attribut mit einem relativen Paket-URI festgelegt, der HomePage.xaml identifiziert. Wenn XBAP gestartet wird, wird automatisch zu HomePage.xaml navigiert und diese Datei angezeigt. Dies wird in der folgenden Abbildung veranschaulicht, in der eine XBAP gezeigt wird, die von einem Webserver gestartet wird.

XBAP-Seite

HinweisHinweis

Weitere Informationen zu Entwicklung und Bereitstellung von XBAPs finden Sie Übersicht über WPF-XAML-Browseranwendungen unter Bereitstellen von WPF-Anwendungen (WPF).

Konfigurieren von Titel, Breite und Höhe des Hostfensters

In der vorherigen Abbildung ist Ihnen möglicherweise aufgefallen, dass der Titel sowohl des Browsers als auch des Registerkartenbereichs dem URI für eine XBAP entspricht. Der Titel ist zum einen lang und zum anderen weder ansprechend noch informativ. Daher bietet Page eine Möglichkeit zum Ändern des Titels, indem die WindowTitle-Eigenschaft festgelegt wird. Darüber hinaus können Sie die Breite und Höhe des Browserfensters durch Festlegen von WindowWidth bzw. WindowHeight konfigurieren.

WindowTitle, WindowWidth und WindowHeight können deklarativ in Markup festgelegt werden, wie im folgenden Beispiel veranschaulicht.

<Page
    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="SDKSample.HomePage"
    WindowTitle="Page Title"
    WindowWidth="500"
    WindowHeight="200">
  Hello, from the XBAP HomePage!
</Page>

Das Ergebnis wird in der folgenden Abbildung dargestellt.

Fenstertitel, -höhe, -breite

Linknavigation

Eine typische XBAP umfasst mehrere Seiten. Mithilfe von Hyperlink kann am einfachsten von einer Seite zur nächsten navigiert werden. Sie können einer Page einen Hyperlink deklarativ hinzufügen, indem Sie das Hyperlink-Element verwenden, das im folgenden Markup veranschaulicht wird.

<Page
  xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
  WindowTitle="Page With Hyperlink"
  WindowWidth="250"
  WindowHeight="250">


...


<Hyperlink NavigateUri="UriOfPageToNavigateTo.xaml">
  Navigate to Another Page
</Hyperlink>


...


</Page>

Für ein Hyperlink-Element benötigen Sie Folgendes:

  • Den Paket-URI der Page, zu der Sie navigieren, wie vom NavigateUri-Attribut angegeben.

  • Inhalt, auf den ein Benutzer zum Einleiten der Navigation klicken kann, z. B. Text und Bilder (Informationen zum Inhalt, den das Hyperlink-Element enthalten kann, finden Sie unter Hyperlink).

In der folgenden Abbildung wird eine XBAP mit Page dargestellt, die einen Hyperlink besitzt.

Seite mit Link

Erwartungsgemäß verursacht das Klicken auf Hyperlink, dass eine XBAP zu Page navigiert, die durch das NavigateUri-Attribut identifiziert wird. Darüber hinaus fügt XBAP der Liste Zuletzt besuchte Seiten in Internet Explorer einen Eintrag für die vorherige Page hinzu. Das wird in der folgenden Abbildung gezeigt.

Zurück- und Vorwärts-Schaltflächen

Genauso wie das Unterstützen der Navigation von einer Page zur anderen, unterstützt Hyperlink auch Fragmentnavigation.

Fragmentnavigation

Fragmentnavigation beschreibt die Navigation zu einem Inhaltsfragment entweder in der aktuellen Page oder in einer anderen Page. In WPF entspricht ein Inhaltsfragment dem Inhalt, der im benannten Element enthalten ist. Ein benanntes Element ist ein Element, dessen Name-Attribut festgelegt wurde. Im folgenden Markup wird ein benanntes TextBlock-Element gezeigt, das ein Inhaltsfragment enthält.

<Page
    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
    WindowTitle="Page With Fragments" >


...


<!-- Content Fragment called "Fragment1" -->
<TextBlock Name="Fragment1">
  Ea vel dignissim te aliquam facilisis ...
</TextBlock>


...


</Page>

Damit ein Hyperlink zu einem Inhaltsfragment navigiert, muss das NavigateUri-Attribut Folgendes einschließen:

  • Den URI von Page mit dem Inhaltsfragment, zu dem navigiert werden soll.

  • Ein "#"-Zeichen

  • Den Namen des Elements für die Page, die das Inhaltsfragment enthält.

Ein Fragment-URI hat das folgende Format.

SeitenURI#Elementname

Im Folgenden finden Sie ein Beispiel für einen Hyperlink, der für die Navigation zu einem Inhaltsfragment konfiguriert ist.

<Page
  xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
  WindowTitle="Page That Navigates To Fragment" >


...


<Hyperlink NavigateUri="PageWithFragments.xaml#Fragment1">
  Navigate To pack Fragment
</Hyperlink>


...


</Page>
HinweisHinweis

In diesem Abschnitt wird die standardmäßige Implementierung der Fragmentnavigation in WPF beschrieben.Mit WPF können Sie Ihr eigenes Fragmentnavigationsschema implementieren, das teilweise die Behandlung des NavigationService.FragmentNavigation-Ereignisses erfordert.

Wichtiger HinweisWichtig

Zu Fragmenten in Loose XAML-Seiten (Markup-XAML-Dateien mit Page als Stammelement) können Sie nur dann navigieren, wenn die Seiten über HTTP gesucht werden können.

Das Navigieren zu den eigenen Fragmenten ist für eine Loose XAML-Seite jedoch möglich.

Mit Hyperlink kann ein Benutzer die Navigation zu einer bestimmten Page initiieren. Das Suchen und Herunterladen der Seite wird durch die NavigationService-Klasse ausgeführt. Im Wesentlichen ermöglicht NavigationService die Verarbeitung einer Navigationsanforderung im Namen eine Clientcodes, z. B. Hyperlink. Darüber hinaus implementiert NavigationService Unterstützung auf höherer Ebene zum Nachverfolgen und Beeinflussen einer Navigationsanforderung.

Wenn Sie auf Hyperlink klicken, ruft WPF den NavigationService.Navigate auf, um Page unter dem angegebenen Paket-URI zu suchen und herunterzuladen. Die heruntergeladene Page wird in eine Struktur von Objekten konvertiert, deren Stammobjekt eine Instanz der heruntergeladenen Page ist. Ein Verweis auf das Page-Stammobjekt wird in der NavigationService.Content-Eigenschaft gespeichert. Der Paket-URI für den Inhalt, zu dem Sie navigiert sind, ist in der NavigationService.Source-Eigenschaft gespeichert. Dagegen speichert NavigationService.CurrentSource den Paket-URI für die letzte Seite, zu der navigiert wurde.

HinweisHinweis

Eine WPF-Anwendung kann mehrere derzeit aktive NavigationService-Elemente haben.Weitere Informationen finden Sie unter Navigationshosts weiter unten in diesem Thema.

Programmgesteuerte Navigation mit dem Navigationsdienst

Sie müssen nichts über NavigationService wissen, wenn die Navigation durch Hyperlink deklarativ im Markup implementiert wird, da Hyperlink in Ihrem Namen NavigationService verwendet. Dies bedeutet, dass Hyperlink den Navigationsdienst des Navigationshosts finden und verwenden kann, um eine Navigationsanforderung zu verarbeiten, solange entweder das direkte oder das indirekte übergeordnete Element von Hyperlink ein Navigationshost ist (siehe Navigationshosts).

Es treten allerdings Situationen auf, in denen Sie NavigationService direkt verwenden müssen, darunter die folgenden:

  • Wenn Sie Page unter Verwendung eines nicht standardmäßigen Konstruktors instanziieren müssen.

  • Wenn Sie Eigenschaften auf Page festlegen müssen, bevor Sie dorthin navigieren.

  • Wenn die Page, zu der navigiert werden muss, nur zur Laufzeit bestimmt werden kann.

In diesen Fällen müssen Sie Code schreiben, um die Navigation programmgesteuert zu initiieren, indem Sie die Navigate-Methode des NavigationService-Objekts aufrufen. Dies macht das Abrufen eines Verweises auf NavigationService erforderlich.

Abrufen eines Verweises auf NavigationService

Aus den im Abschnitt Navigationshosts genannten Gründen kann eine WPF-Anwendung mehrere NavigationService-Elemente haben. Daher muss Ihr Code in der Lage sein, nach einem NavigationService zu suchen. In der Regel handelt es sich dabei um den NavigationService, der zur aktuellen Page navigiert ist. Sie können einen Verweis auf einen NavigationService abrufen, indem Sie die static NavigationService.GetNavigationService-Methode aufrufen. Zum Abrufen von NavigationService, der zu einer bestimmten Page navigiert ist, übergeben Sie einen Verweis auf Page als Argument der GetNavigationService-Methode. Im folgenden Code wird das Abrufen von NavigationService für die aktuelle Page dargestellt.

' Get a reference to the NavigationService that navigated to this Page
Dim ns As NavigationService = NavigationService.GetNavigationService(Me)
using System.Windows.Navigation; // NavigationServce


...


// Get a reference to the NavigationService that navigated to this Page
NavigationService ns = NavigationService.GetNavigationService(this);

Als Arbeitserleichterung zum Suchen von NavigationService für Page implementiert Page die NavigationService-Eigenschaft. Dies wird im folgenden Beispiel gezeigt.

' Get a reference to the NavigationService that navigated to this Page
Dim ns As NavigationService = Me.NavigationService
using System.Windows.Navigation; // NavigationServce


...


// Get a reference to the NavigationService that navigated to this Page
NavigationService ns = this.NavigationService;
HinweisHinweis

Eine Page kann einen Verweis auf NavigationService nur dann abrufen, wenn Page das Loaded-Ereignis auslöst.

Programmgesteuerte Navigation zu einem Seitenobjekt

Im folgenden Beispiel wird die Verwendung von NavigationService zur programmgesteuerten Navigation zu Page veranschaulicht. Programmgesteuerte Navigation wird benötigt, da die Page, zu der navigiert wird, nur über einen einzelnen, nicht standardmäßigen Konstruktor instanziiert werden kann. Die Page mit dem nicht standardmäßigen Konstruktor wird im folgenden Markup und Code gezeigt.

<Page
    x:Class="SDKSample.PageWithNonDefaultConstructor"
    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
    Title="PageWithNonDefaultConstructor">

  <!-- Content goes here -->

</Page>

Namespace SDKSample
    Partial Public Class PageWithNonDefaultConstructor
        Inherits Page
        Public Sub New(ByVal message As String)
            InitializeComponent()

            Me.Content = message
        End Sub
    End Class
End Namespace
using System.Windows.Controls; // Page

namespace SDKSample
{
    public partial class PageWithNonDefaultConstructor : Page
    {
        public PageWithNonDefaultConstructor(string message)
        {
            InitializeComponent();

            this.Content = message;
        }
    }
}

Die Page, die zu Page mit dem nicht standardmäßigen Konstruktor navigiert, wird im folgenden Markup und Code gezeigt.

<Page
    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="SDKSample.NSNavigationPage">

  <Hyperlink Click="hyperlink_Click">
    Navigate to Page with Non-Default Constructor
  </Hyperlink>

</Page>

Namespace SDKSample
    Partial Public Class NSNavigationPage
        Inherits Page
        Public Sub New()
            InitializeComponent()
        End Sub

        Private Sub hyperlink_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
            ' Instantiate the page to navigate to
            Dim page As New PageWithNonDefaultConstructor("Hello!")

            ' Navigate to the page, using the NavigationService
            Me.NavigationService.Navigate(page)
        End Sub
    End Class
End Namespace
using System.Windows; // RoutedEventArgs
using System.Windows.Controls; // Page
using System.Windows.Navigation; // NavigationService

namespace SDKSample
{
    public partial class NSNavigationPage : Page
    {
        public NSNavigationPage()
        {
            InitializeComponent();
        }

        void hyperlink_Click(object sender, RoutedEventArgs e)
        {
            // Instantiate the page to navigate to
            PageWithNonDefaultConstructor page = new PageWithNonDefaultConstructor("Hello!");

            // Navigate to the page, using the NavigationService
            this.NavigationService.Navigate(page);
        }
    }
}

Wenn auf dieser Page auf Hyperlink geklickt wird, wird die Navigation durch Instanziieren der Page eingeleitet, zu der navigiert wird, indem der nicht standardmäßige Konstruktor verwendet und die NavigationService.Navigate-Methode aufgerufen wird. Navigate akzeptiert einen Verweis auf das Objekt, zu dem NavigationService navigiert, jedoch keinen Paket-URI.

Programmgesteuerte Navigation mit einem Paket-URI

Wenn Sie einen Paket-URI programmgesteuert erstellen müssen (falls der Paket-URI beispielsweise nur zur Laufzeit bestimmt werden kann), können Sie die NavigationService.Navigate-Methode verwenden. Dies wird im folgenden Beispiel gezeigt.

<Page
    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="SDKSample.NSUriNavigationPage">
  <Hyperlink Click="hyperlink_Click">Navigate to Page by Pack URI</Hyperlink>
</Page>

Namespace SDKSample
    Partial Public Class NSUriNavigationPage
        Inherits Page
        Public Sub New()
            InitializeComponent()
        End Sub

        Private Sub hyperlink_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
            ' Create a pack URI
            Dim uri As New Uri("AnotherPage.xaml", UriKind.Relative)

            ' Get the navigation service that was used to 
            ' navigate to this page, and navigate to 
            ' AnotherPage.xaml
            Me.NavigationService.Navigate(uri)
        End Sub
    End Class
End Namespace
using System; // Uri, UriKind
using System.Windows; // RoutedEventArgs
using System.Windows.Controls; // Page
using System.Windows.Navigation; // NavigationService

namespace SDKSample
{
    public partial class NSUriNavigationPage : Page
    {
        public NSUriNavigationPage()
        {
            InitializeComponent();
        }

        void hyperlink_Click(object sender, RoutedEventArgs e)
        {
            // Create a pack URI
            Uri uri = new Uri("AnotherPage.xaml", UriKind.Relative);

            // Get the navigation service that was used to 
            // navigate to this page, and navigate to 
            // AnotherPage.xaml
            this.NavigationService.Navigate(uri);
        }
    }
}

Aktualisieren der aktuellen Seite

Eine Page wird nicht heruntergeladen, wenn sie denselben Paket-URI besitzt wie der Paket-URI, der in der NavigationService.Source-Eigenschaft gespeichert wird. Wenn Sie erzwingen möchten, dass WPF die aktuelle Seite erneut herunterlädt, können Sie die NavigationService.Refresh-Methode aufrufen, wie im folgenden Beispiel dargestellt.

<Page
    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="SDKSample.NSRefreshNavigationPage">
 <Hyperlink Click="hyperlink_Click">Refresh this page</Hyperlink>
</Page>

Namespace SDKSample
    Partial Public Class NSRefreshNavigationPage
        Inherits Page


...


        Private Sub hyperlink_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
            ' Force WPF to download this page again
            Me.NavigationService.Refresh()
        End Sub
    End Class
End Namespace
using System.Windows; // RoutedEventArgs
using System.Windows.Controls; // Page
using System.Windows.Navigation; // NavigationService

namespace SDKSample
{
    public partial class NSRefreshNavigationPage : Page
    {


...


        void hyperlink_Click(object sender, RoutedEventArgs e)
        {
            // Force WPF to download this page again
            this.NavigationService.Refresh();
        }
    }
}

Wie Sie sehen, gibt es viele Möglichkeiten zum Einleiten der Navigation. Nachdem die Navigation initiiert wurde und während sie ausgeführt wird, können Sie die Navigation mit den folgenden Ereignissen, die von NavigationService implementiert werden, nachverfolgen und beeinflussen:

  • Navigating. Tritt ein, wenn eine neue Navigation angefordert wird. Kann zum Abbrechen der Navigation verwendet werden.

  • NavigationProgress. Tritt während eines Downloads regelmäßig ein, um Informationen zum Navigationsfortschritt bereitzustellen.

  • Navigated. Tritt ein, nachdem die Seite gefunden und heruntergeladen wurde.

  • NavigationStopped. Tritt ein, nachdem die Navigation (durch Aufrufen von StopLoading) angehalten wurde oder wenn eine neue Navigation angefordert wird, während die aktuelle Navigation noch ausgeführt wird.

  • NavigationFailed. Tritt ein, wenn ein Fehler ausgelöst wird, während zum angeforderten Inhalt navigiert wird.

  • LoadCompleted. Tritt ein, wenn der Inhalt, zu dem navigiert wurde, geladen und analysiert wird und mit dem Rendering begonnen wurde.

  • FragmentNavigation. Tritt ein, wenn die Navigation zu einem Inhaltsfragment beginnt, was in folgenden Fällen geschieht:

    • Sofort, falls sich das gewünschte Fragment im aktuellen Inhalt befindet.

    • Nachdem der Inhalt der Quelldatei geladen wurde und sich das gewünschte Fragment in einem anderen Inhalt befindet.

Die Navigationsereignisse werden in der Reihenfolge ausgelöst, die in der folgenden Abbildung dargestellt wird.

Seitennavigations-Flussdiagramm

Im Allgemeinen befasst sich Page nicht mit diesen Ereignissen. Es ist viel wahrscheinlicher, dass sich eine Anwendung mit ihnen befasst. Aus diesem Grund werden diese Ereignisse ebenfalls von der Application-Klasse ausgelöst:

Jedes Mal, wenn NavigationService ein Ereignis auslöst, löst die Application-Klasse das entsprechende Ereignis aus. Frame und NavigationWindow bieten dieselben Ereignisse, mit denen Navigation in ihren jeweiligen Gültigkeitsbereichen erkannt wird.

In einigen Fällen könnten diese Ereignisse für Page von Interesse sein. Eine Page könnte beispielsweise das NavigationService.Navigating-Ereignis verarbeiten, um zu bestimmen, ob die Navigation von der Seite weg abgebrochen werden soll. Dies wird im folgenden Beispiel gezeigt.

<Page
    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="SDKSample.CancelNavigationPage">
  <Button Click="button_Click">Navigate to Another Page</Button>
</Page>

Namespace SDKSample
    Partial Public Class CancelNavigationPage
        Inherits Page
        Public Sub New()
            InitializeComponent()

            ' Can only access the NavigationService when the page has been loaded
            AddHandler Loaded, AddressOf CancelNavigationPage_Loaded
            AddHandler Unloaded, AddressOf CancelNavigationPage_Unloaded
        End Sub

        Private Sub button_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
            ' Force WPF to download this page again
            Me.NavigationService.Navigate(New Uri("AnotherPage.xaml", UriKind.Relative))
        End Sub

        Private Sub CancelNavigationPage_Loaded(ByVal sender As Object, ByVal e As RoutedEventArgs)
            AddHandler NavigationService.Navigating, AddressOf NavigationService_Navigating
        End Sub

        Private Sub CancelNavigationPage_Unloaded(ByVal sender As Object, ByVal e As RoutedEventArgs)
            RemoveHandler NavigationService.Navigating, AddressOf NavigationService_Navigating
        End Sub

        Private Sub NavigationService_Navigating(ByVal sender As Object, ByVal e As NavigatingCancelEventArgs)
            ' Does the user really want to navigate to another page?
            Dim result As MessageBoxResult
            result = MessageBox.Show("Do you want to leave this page?", "Navigation Request", MessageBoxButton.YesNo)

            ' If the user doesn't want to navigate away, cancel the navigation
            If result = MessageBoxResult.No Then
                e.Cancel = True
            End If
        End Sub
    End Class
End Namespace
using System; // Uri, UriKind
using System.Windows; // RoutedEventArgs, MessageBox, MessageBoxResult
using System.Windows.Controls; // Page
using System.Windows.Navigation; // NavigationService, NavigatingCancelEventArgs

namespace SDKSample
{
    public partial class CancelNavigationPage : Page
    {
        public CancelNavigationPage()
        {
            InitializeComponent();

            // Can only access the NavigationService when the page has been loaded
            this.Loaded += new RoutedEventHandler(CancelNavigationPage_Loaded);
            this.Unloaded += new RoutedEventHandler(CancelNavigationPage_Unloaded);
        }

        void button_Click(object sender, RoutedEventArgs e)
        {
            // Force WPF to download this page again
            this.NavigationService.Navigate(new Uri("AnotherPage.xaml", UriKind.Relative));
        }

        void CancelNavigationPage_Loaded(object sender, RoutedEventArgs e)
        {
            this.NavigationService.Navigating += new NavigatingCancelEventHandler(NavigationService_Navigating);
        }

        void CancelNavigationPage_Unloaded(object sender, RoutedEventArgs e)
        {
            this.NavigationService.Navigating -= new NavigatingCancelEventHandler(NavigationService_Navigating);
        }

        void NavigationService_Navigating(object sender, NavigatingCancelEventArgs e)
        {
            // Does the user really want to navigate to another page?
            MessageBoxResult result;
            result = MessageBox.Show("Do you want to leave this page?", "Navigation Request", MessageBoxButton.YesNo);

            // If the user doesn't want to navigate away, cancel the navigation
            if (result == MessageBoxResult.No) e.Cancel = true;
        }
    }
}

Wenn Sie einen Handler für ein Navigationsereignis aus Page registrieren (siehe vorheriges Beispiel), dann müssen Sie auch die Registrierung des Ereignishandlers aufheben. Wenn Sie das versäumen, kann das Nebeneffekte im Hinblick darauf auslösen, wie die WPF-Navigation die Page-Navigation mithilfe des Journals speichert.

Aufzeichnung der Navigation mithilfe des Journals

WPF verwendet zwei Stapel, um die Seiten zu speichern, von denen Sie weg navigiert sind: jeweils einen Stapel für die Rückwärts- und einen Stapel für die Vorwärtsnavigation. Wenn Sie von der aktuellen Page zu einer neuen Page oder vorwärts zu einer vorhandenen Page navigieren, wird dem Rückwärtsstapel die aktuelle Page hinzugefügt. Wenn Sie von der aktuellen Page zurück zur vorherigen Page navigieren, wird dem Vorwärtsstapel die aktuelle Page hinzugefügt. Der Rückwärts- und der Vorwärtsstapel sowie die Funktion zum Verwalten der Stapel werden zusammen als das Journal bezeichnet. Jedes Element in den beiden Stapeln stellt eine Instanz der JournalEntry-Klasse dar und wird als Journaleintrag bezeichnet.

Prinzipiell funktioniert das Journal auf dieselbe Weise wie die Schaltflächen Zurück und Vorwärts in Internet Explorer. Diese sind in der folgenden Abbildung dargestellt.

Zurück- und Vorwärts-Schaltflächen

Bei XBAPs, die von Internet Explorer gehostet werden, integriert WPF das Journal in die Navigations-UI von Internet Explorer. Auf diese Weise können Benutzer zu Seiten in einer XBAP navigieren, indem sie die Schaltflächen Zurück, Vorwärts und Zuletzt besuchte Seiten in Internet Explorer verwenden. Das Journal wird in Microsoft Internet Explorer 6 nicht auf dieselbe Weise integriert wie in Internet Explorer 7 oder Internet Explorer 8. Stattdessen rendert WPF eine Ersatznavigations-UI.

Wichtiger HinweisWichtig

Wenn ein Benutzer in Internet Explorer von XBAP weg und wieder dorthin zurück navigiert, werden nur die Journaleinträge für Seiten, die nicht aktiv beibehalten wurden, im Journal beibehalten.Eine Erklärung, wie Sie Seiten beibehalten, finden Sie unter Seitenlebensdauer und das Journal weiter unten in diesem Thema.

Standardmäßig entspricht der Text für jede Page, die in der Liste Zuletzt besuchte Seiten von Internet Explorer angezeigt wird, dem URI für Page. In vielen Fällen ist das für den Benutzer nicht besonders sinnvoll. Sie können den Text jedoch mithilfe einer der folgenden Optionen ändern:

  1. Dem angefügten JournalEntry.Name-Attributwert

  2. Dem Page.Title-Attributwert

  3. Dem Page.WindowTitle-Attributwert und dem URI für die aktuelle Page

  4. Dem URI für die aktuelle Page. (Standard)

Die Reihenfolge, in der die Optionen aufgeführt sind, entspricht der Rangfolge zum Suchen von Text. Wenn JournalEntry.Name festgelegt wurde, werden die anderen Werte beispielsweise ignoriert.

Im folgenden Beispiel wird das Page.Title-Attribut verwendet, um den Text zu ändern, der für einen Journaleintrag angezeigt wird.

<Page
    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="SDKSample.PageWithTitle"
    Title="This is the title of the journal entry for this page.">


...


</Page>

Namespace SDKSample
    Partial Public Class PageWithTitle
        Inherits Page


...


    End Class
End Namespace
using System.Windows.Controls; // Page

namespace SDKSample
{
    public partial class PageWithTitle : Page
    {


...


    }
}

Obwohl der Benutzer mithilfe der Schaltflächen Zurück, Vorwärts und Zuletzt besuchte Seiten in Internet Explorer im Journal navigieren kann, können Sie auch sowohl mit dem deklarativen als auch mit dem programmgesteuerten Mechanismus von WPF im Journal navigieren. Ein Grund dafür besteht darin, benutzerdefinierte Navigations-UIs in den Seiten zur Verfügung zu stellen.

Sie können die Unterstützung der Journalnavigation deklarativ hinzufügen, indem Sie die Navigationsbefehle verwenden, die von NavigationCommands verfügbar gemacht werden. Im folgenden Beispiel wird die Verwendung des BrowseBack-Navigationsbefehls erläutert.

<Page
    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="SDKSample.NavigationCommandsPage">


...


<Hyperlink Command="NavigationCommands.BrowseBack">Back</Hyperlink>


...


<Hyperlink Command="NavigationCommands.BrowseForward">Forward</Hyperlink>


...


</Page>

Sie können programmgesteuert mit einem der folgenden Member der NavigationService-Klasse im Journal navigieren:

Das Journal kann auch programmgesteuert geändert werden, wie in Beibehalten des Inhaltszustands über den Navigationsverlauf weiter unten in diesem Thema erläutert wird.

Seitenlebensdauer und das Journal

Beispiel: Eine XBAP mit mehreren Seiten, die umfangreichem Inhalt, einschließlich Grafiken, Animationen und Medien, enthalten. Die Speicherbeanspruchung für Seiten wie diese könnte recht groß sein, insbesondere, wenn Video- und Audiomedien verwendet werden. Wenn das Journal Seiten "speichert", zu denen navigiert wurde, könnte XBAP schnell einen beträchtlichen Speicherplatz belegen.

Aus diesem Grund besteht das Standardverhalten des Journals im Speichern von Page-Metadaten in jedem Journaleintrag, anstatt auf ein Page-Objekt zu verweisen. Wird zu einem Journaleintrag navigiert, werden seine Page-Metadaten zum Erstellen einer neuen Instanz der angegebenen Page verwendet. Folglich hat jede Page, zu der navigiert wird, die in der folgenden Abbildung dargestellte Lebensdauer.

Seitenlebensdauer

Obwohl das Standardverhalten des Journals zu einer geringeren Speicherauslastung führen kann, kann die Leistung beim Rendern pro Seite gemindert werden; das erneute Instanziieren von Page kann zeitaufwändig sein, insbesondere bei umfangreichem Inhalt. Wenn Sie eine Page-Instanz im Journal beibehalten müssen, können Sie hierzu die folgenden beiden Techniken verwenden. Navigieren Sie zuerst programmgesteuert zu einem Page-Objekt, indem Sie die NavigationService.Navigate-Methode aufrufen.

Als Nächstes können Sie angeben, dass WPF eine Instanz von Page im Journal beibehält, indem die KeepAlive-Eigenschaft auf true (der Standard ist false) festgelegt wird. Sie können KeepAlive deklarativ in Markup festlegen, wie im folgenden Beispiel veranschaulicht.

<Page
    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="SDKSample.KeepAlivePage"
    KeepAlive="True">

  An instance of this page is stored in the journal.

</Page>

Die Lebensdauer einer aktiv beibehaltenen Page unterscheidet sich nur wenig von einer nicht beibehaltenen Seite. Beim ersten Navigieren zu einer Page, die aktiv beibehalten wird, wird diese wie eine Page instanziiert, die nicht aktiv beibehalten wird. Da jedoch eine Instanz von Page im Journal beibehalten wird, wird sie für die Dauer ihrer Aufbewahrung im Journal nicht mehr instanziiert. Wenn eine Page also eine Initialisierungslogik hat, die bei jedem Navigieren zu Page aufgerufen werden muss, sollten Sie sie aus dem Konstruktor in einen Handler für das Loaded-Ereignis verschieben. Wie in der folgenden Abbildung dargestellt, werden das Loaded-Ereignis und das Unloaded-Ereignis nach wie vor jedes Mal ausgelöst, wenn zu Page hin und wieder zurücknavigiert wird.

Wenn die Loaded- und Unloaded-Ereignisse ausgelöst werden

Wenn Page nicht aktiv beibehalten wird, sollten Sie Folgendes unterlassen:

  • Speichern eines Verweises auf die Seite oder einen Teil der Seite

  • Registrieren von Ereignishandlern für Ereignisse, die nicht von ihr implementiert werden

Mit jedem dieser Schritte werden Verweise erstellt, die erzwingen, dass Page im Speicher beibehalten wird, nachdem sie aus dem Journal entfernt wurde.

Im Allgemeinen sollten Sie das Standardverhalten von Page vorziehen, d.h. Page nicht aktiv beibehalten. Dies zieht jedoch Auswirkungen auf den Zustand nach sich, die im nächsten Abschnitt erörtert werden.

Beibehalten des Inhaltszustands über den Navigationsverlauf

Angenommen, Page wird nicht aktiv beibehalten und verfügt über Steuerelemente, die Benutzerdaten erfassen. Wie wirkt es sich auf die Daten aus, wenn ein Benutzer von Page weg und dorthin zurück navigiert? Aus Gründen der Benutzererfahrung sollte der Benutzer erwarten, dass die zuvor eingegebenen Daten angezeigt werden. Da mit jeder Navigation eine neue Instanz von Page erstellt wird, werden die Steuerelemente, die die Daten erfasst haben, jedoch neu instanziiert, und die Daten gehen verloren.

Das Journal unterstützt jedoch das Speichern von Daten über Page-Navigationen hinweg, einschließlich Steuerelementdaten. Insbesondere der Journaleintrag für jede Page fungiert als temporärer Container für den zugeordneten Page-Zustand. In den folgenden Schritten wird beschrieben, wie diese Unterstützung verwendet wird, wenn von Page weg navigiert wird:

  1. Dem Journal wird ein Eintrag für die aktuelle Page hinzugefügt.

  2. Der Zustand von Page wird im Journaleintrag für diese Seite gespeichert, die dem Rückwärtsstapel hinzugefügt wird.

  3. Es wird zur neuen Page navigiert.

Wenn zurück zur Seite Page navigiert wird, werden beim Verwenden des Journals die folgenden Schritte ausgeführt:

  1. Die Page (der oberste Journaleintrag im Rückwärtsstapel) wird instanziiert.

  2. Die Page wird mit dem Zustand aktualisiert, der mit dem Journaleintrag für Page gespeichert wurde.

  3. Es wird zurück zur neuen Page navigiert.

WPF verwendet diese Unterstützung automatisch, wenn die folgenden Steuerelemente für Page verwendet werden:

Wenn Page diese Steuerelemente verwendet, werden die dort eingegebenen Daten über Page-Navigationen hinweg gespeichert, wie durch Bevorzugte Farbe ListBox in der folgenden Abbildung veranschaulicht wird.

Seite mit Steuerelementen, die den Zustand speichern

Wenn eine Page andere Steuerelemente aufweist als die oben aufgeführten oder wenn ein Zustand in benutzerdefinierten Objekten gespeichert wird, müssen Sie Code schreiben, durch den das Journal den Zustand über Page-Navigationen hinweg speichert.

Wenn Sie kleinere Mengen der Zustandsinformationen über Page-Navigationen hinweg speichern müssen, können Sie Abhängigkeitseigenschaften verwenden (siehe DependencyProperty), die mit dem FrameworkPropertyMetadata.Journal-Metadatenflag konfiguriert werden.

Wenn der Zustand, den Page über mehrere Navigationen hinweg speichern muss, aus mehreren Datenmengen besteht, kann sich das Kapseln Ihres Zustands in einer einzelnen Klasse und Implementieren der IProvideCustomContentState-Schnittstelle als weniger codeintensiv erweisen.

Wenn Sie durch verschiedene Zustände einer einzelnen Page navigieren müssen, können Sie IProvideCustomContentState und NavigationService.AddBackEntry verwenden, ohne von Page weg zu navigieren.

Cookies

WPF-Anwendungen können Daten auch mit Cookies speichern, die unter Verwendung der SetCookie-Methode und der GetCookie-Methode erstellt, aktualisiert und gelöscht werden. Die Cookies, die Sie in WPF erstellen können, sind mit den Cookies identisch, die von anderen Webanwendungen verwendet werden. Cookies bestehen aus willkürlichen Daten, die von einer Anwendung entweder während oder über Anwendungssitzungen hinweg auf einem Clientcomputer gespeichert werden. Cookiedaten weisen meist das folgende Format eines Name-Wert-Paares auf.

Name=Wert

Wenn die Daten an SetCookie übergeben werden, wird zusammen mit dem Uri des Standorts, für den das Cookie festgelegt werden soll, ein Cookie speicherintern erstellt. Für die Dauer der aktuellen Anwendungssitzung ist es das einzig verfügbare Cookie. Diese Art von Cookies wird als Sitzungscookie bezeichnet.

Wenn Sie ein Cookie über Anwendungssitzungen speichern möchten, muss dem Cookie unter Verwendung des folgenden Formats ein Ablaufdatum hinzugefügt werden.

NAME=WERT; expires=DAY, DD-MMM-YYYY HH:MM:SS GMT

Ein Cookie mit einem Ablaufdatum wird im Ordner Temporäre Internetdateien der aktuellen Windows-Installation gespeichert, bis das Cookie abläuft. Ein solches Cookie wird als dauerhaftes Cookie bezeichnet, da es über Anwendungssitzungen erhalten bleibt.

Sie rufen sowohl Sitzungscookies als auch dauerhafte Cookies auf, indem Sie die GetCookie-Methode aufrufen. Dabei übergeben Sie den Uri des Speicherorts, an dem das Cookie festgelegt wurde, mit der SetCookie-Methode.

Im Folgenden werden einige der Methoden zum Unterstützen von Cookies in WPF dargestellt:

  • Eigenständige WPF-Anwendungen und XBAPs können Cookies erstellen und verwalten.

  • Auf Cookies, die von XBAP erstellt werden, kann vom Browser zugegriffen werden.

  • XBAPs aus derselben Domäne können Cookies erstellen und gemeinsam verwenden.

  • XBAPs- und HTML-Seiten aus derselben Domäne können Cookies erstellen und gemeinsam verwenden.

  • Cookies werden gesendet, wenn XBAPs und Loose XAML-Seiten Webanforderungen stellen.

  • Die XBAPs der oberen Ebene und XBAPs, die in IFRAMES gehostet werden, können auf Cookies zugreifen.

  • Die Cookieunterstützung in WPF ist für alle unterstützten Browser gleich.

  • In Internet Explorer wird die P3P-Richtlinie, die Cookies betrifft, von WPF berücksichtigt, insbesondere in Bezug auf XBAPs von Erst- und Drittanbietern.

Strukturierte Navigation

Wenn Sie Daten von einer Page zur anderen übergeben müssen, können Sie die Daten als Argumente an einen nicht standardmäßigen Konstruktor von Page übergeben. Beachten Sie, dass Sie bei der Verwendung dieses Verfahrens Page aktiv beibehalten müssen. Andernfalls wird WPF Page beim nächsten Navigieren zu Page mithilfe des standardmäßigen Konstruktors erneut instanziiert.

Alternativ dazu kann Page Eigenschaften implementieren, die mit den zu übergebenden Daten festgelegt werden. Kompliziert wird dies, wenn Page Daten zurück an die Page übergeben muss, die dorthin navigiert ist. Das Problem besteht darin, dass die Navigation keine direkte Unterstützung für Mechanismen bietet, die garantieren können, dass zu einer Page zurückgekehrt wird, nachdem von ihr weg navigiert wurde. Im Grunde unterstützt die Navigation keine Semantik mit Aufruf/Rückgabe. Zur Behebung dieses Problems stellt WPF die PageFunction<T>-Klasse zur Verfügung, mit der Sie sicherstellen können, dass in einer vorhersehbaren und strukturierten Weise zu Page zurückgekehrt wird. Weitere Informationen finden Sie unter Übersicht über die strukturierte Navigation.

Die NavigationWindow-Klasse

Bis jetzt haben Sie das Spektrum der Navigationsdienste kennengelernt, die Sie zum Erstellen von Anwendungen mit navigierbarem Inhalt normalerweise verwenden werden. Diese Dienste wurden im Kontext von XBAPs behandelt, obwohl sie nicht auf XBAPs beschränkt sind. Moderne Betriebssysteme und Windows-Anwendungen nutzen die Browsererfahrung zeitgemäßer Benutzer, um die Navigation im Browserstil in eigenständige Anwendungen zu integrieren. Gängige Beispiele:

  • Word-Thesaurus: Navigieren durch verschiedene Benennungen (Synonyme)

  • Datei-Explorer: Navigieren in Dateien und Ordnern

  • Assistenten: Untergliedern einer komplexen Aufgabe in mehrere Seiten, zwischen denen navigiert werden kann. Ein Beispiel ist der Assistent für Windows-Komponenten, der das Hinzufügen und Entfernen von Windows-Features verarbeitet.

Um die Navigation im Browserstil in Ihre eigenständigen Anwendungen zu integrieren, können Sie die NavigationWindow-Klasse verwenden. NavigationWindow wird von Window abgeleitet und bietet die gleiche Navigationsunterstützung wie XBAPs. Verwenden Sie NavigationWindow entweder als Hauptfenster der eigenständigen Anwendung oder als sekundäres Fenster, z. B. ein Dialogfeld.

Wenn Sie NavigationWindow implementieren möchten, verwenden Sie, wie bei den meisten Klassen der obersten Ebene in WPF (Window, Page usw.), eine Kombination aus Markup und Code-Behind. Dies wird im folgenden Beispiel gezeigt.

<NavigationWindow
    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="SDKSample.MainWindow" 
    Source="HomePage.xaml"/>

Namespace SDKSample
    Partial Public Class MainWindow
        Inherits NavigationWindow
        Public Sub New()
            InitializeComponent()
        End Sub
    End Class
End Namespace
using System.Windows.Navigation; // NavigationWindow

namespace SDKSample
{
    public partial class MainWindow : NavigationWindow
    {
        public MainWindow()
        {
            InitializeComponent();
        }
    }
}

Mit diesem Code wird ein NavigationWindow erstellt, das automatisch zu Page (HomePage.xaml) navigiert, wenn NavigationWindow geöffnet wird. Wenn NavigationWindow das Hauptanwendungsfenster ist, können Sie das StartupUri-Attribut verwenden, um es zu öffnen. Dies wird im folgenden Markup gezeigt.

<Application
    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
    StartupUri="MainWindow.xaml" />

In der folgenden Abbildung wird NavigationWindow als Hauptanwendungsfenster einer eigenständigen Anwendung gezeigt.

Ein Hauptfenster

Sie können in der Abbildung sehen, dass NavigationWindow einen Titel hat, obwohl dies nicht im NavigationWindow-Implementierungscode aus dem vorherigen Beispiel festgelegt wurde. Stattdessen wurde der Titel mithilfe der WindowTitle-Eigenschaft festgelegt, die im folgenden Code dargestellt wird.

<Page 
    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
    Title="Home Page"
    WindowTitle="NavigationWindow">


...


</Page>

Das Festlegen der WindowWidth-Eigenschaft und der WindowHeight-Eigenschaft wirkt sich auch auf NavigationWindow aus.

Normalerweise implementieren Sie Ihr eigenes NavigationWindow, wenn Sie entweder das Verhalten oder die Anzeige anpassen müssen. Wenn keines von beiden angepasst werden muss, können Sie eine Verknüpfung verwenden. Wenn Sie den Paket-URI von Page als StartupUri in einer eigenständigen Anwendung angeben, erstellt Application automatisch NavigationWindow zum Hosten von Page. Im folgenden Markup wird gezeigt, wie Sie das aktivieren.

<Application
    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
    StartupUri="HomePage.xaml" />

Wenn Sie möchten, dass ein sekundäres Anwendungsfenster (z. B. ein Dialogfenster) ein NavigationWindow ist, können Sie den Code aus dem folgenden Beispiel verwenden, um es zu öffnen.

            ' Open a navigation window as a dialog box
            Dim dlg As New NavigationWindowDialogBox()
            dlg.Source = New Uri("HomePage.xaml", UriKind.Relative)
            dlg.Owner = Me
            dlg.ShowDialog()
// Open a navigation window as a dialog box
NavigationWindowDialogBox dlg = new NavigationWindowDialogBox();
dlg.Source = new Uri("HomePage.xaml", UriKind.Relative);
dlg.Owner = this;
dlg.ShowDialog();

In der folgenden Abbildung wird das Ergebnis dargestellt.

Ein Dialogfeld

Wie Sie sehen, zeigt NavigationWindow die Schaltflächen Zurück und Vorwärts, mit denen Benutzer im Journal navigieren können, im Stil von Internet Explorer an. Wie in der folgenden Abbildung veranschaulicht, bieten diese Schaltflächen dieselbe Benutzererfahrung.

Zurück- und Vorwärts-Schaltflächen in einem NavigationWindow

Wenn Ihre Seiten eine eigene Navigationsunterstützung für Journal und Benutzeroberfläche zur Verfügung stellen, können Sie die Schaltflächen Zurück und Vorwärts, die von NavigationWindow angezeigt werden, ausblenden, indem Sie den Wert der ShowsNavigationUI-Eigenschaft auf false festlegen.

Wahlweise können Sie die Unterstützung der Anpassung in WPF verwenden, um die UI von NavigationWindow selbst zu ersetzen.

Die Frame-Klasse

Sowohl Browser und NavigationWindow sind Fenster, die navigierbaren Inhalt hosten. In einigen Fällen verfügen Anwendungen über Inhalt, der nicht von einem ganzen Fenster gehostet werden muss. Stattdessen kann solcher Inhalt in anderem Inhalt gehostet werden. Sie können navigierbaren Inhalt in anderen Inhalt einfügen, indem Sie die Frame-Klasse verwenden. Frame bietet dieselbe Unterstützung wie NavigationWindow und XBAPs.

Im folgenden Beispiel wird gezeigt, wie Sie Page das Element Frame deklarativ hinzufügen, indem Sie das Frame-Element verwenden.

<Page 
  xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
  WindowTitle="Page that Hosts a Frame"
  WindowWidth="250"
  WindowHeight="250">


...


<Frame Source="FramePage1.xaml" />


...


</Page>

Mit diesem Markup wird das Source-Attribut des Frame-Elements mit einem Paket-URI für Page festgelegt, zu der Frame zunächst navigieren sollte. In der folgenden Abbildung wird eine XBAP mit Page angezeigt, die einen Frame aufweist, der zwischen mehreren Seiten navigiert ist.

Ein Frame, der zwischen mehreren Seiten navigiert

Sie sind nicht auf die Verwendung von Frame innerhalb des Inhalts von Page beschränkt. Es ist auch üblich, Frame im Inhalt von Window zu hosten.

Standardmäßig verwendet Frame nur sein eigenes Journal, wenn kein anderes angegeben ist. Wenn ein Frame Teil des Inhalts ist, der in einem NavigationWindow oder einer XBAP gehostet wird, verwendet Frame das Journal, das zu NavigationWindow oder XBAP gehört. Allerdings kommt es vor, dass ein Frame für das eigene Journal zuständig ist. Ein Grund dafür besteht darin, eine Navigation mithilfe des Journals innerhalb der Seiten zu ermöglichen, die durch Frame gehostet werden. Dies wird in der folgenden Abbildung verdeutlicht.

Frame- und Seiten-Diagramm

Sie können Frame in diesem Fall so konfigurieren, dass sein eigenes Journal verwendet wird. Dazu legen Sie die JournalOwnership-Eigenschaft von Frame auf OwnsJournal fest. Dies wird im folgenden Markup gezeigt.

<Page 
  xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
  WindowTitle="Page that Hosts a Frame"
  WindowWidth="250"
  WindowHeight="250">


...


<Frame Source="FramePage1.xaml" JournalOwnership="OwnsJournal" />


...


</Page>

In der folgenden Abbildung wird die Auswirkung der Navigation in Frame dargestellt, der sein eigenes Journal verwendet.

Ein Frame mit einem eigenen Journal

Beachten Sie, dass die Journaleinträge von der Navigations-UI im Frame angezeigt werden und nicht von Internet Explorer.

HinweisHinweis

Wenn Frame Teil des Inhalts ist, der in Window gehostet wird, verwendet Frame das eigene Journal und zeigt folglich die eigene Navigations-UI an.

Wenn Ihre Benutzererfahrung es erforderlich macht, dass Frame ein eigenes Journal zur Verfügung stellt, ohne dass die Navigations-UI angezeigt wird, können Sie die Navigations-UI ausblenden, indem Sie NavigationUIVisibility auf Hidden festlegen. Dies wird im folgenden Markup gezeigt.

<Page 
  xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
  WindowTitle="Page that Hosts a Frame"
  WindowWidth="250"
  WindowHeight="250">


...


<Frame 
  Source="FramePage1.xaml" 
  JournalOwnership="OwnsJournal" 
  NavigationUIVisibility="Hidden" />


...


</Page>

Frame und NavigationWindow sind Klassen, die als Navigationshosts bezeichnet werden. Ein Navigationshost ist eine Klasse, die zu Inhalt navigieren und diesen anzeigen kann. Hierzu verwendet jeder Navigationshost den eigenen NavigationService und das eigene Journal. Die grundlegende Konstruktion eines Navigationshosts wird in der folgenden Abbildung gezeigt.

Navigatordiagramme

Im Wesentlichen erlaubt dies NavigationWindow und Frame, dieselbe Navigationsunterstützung zur Verfügung zu stellen, die eine XBAP verfügbar macht, wenn sie im Browser gehostet wird.

Neben dem Verwenden von NavigationService und einem Journal, implementieren Navigationshosts dieselben Member, die NavigationService implementiert. Dies wird in der folgenden Abbildung verdeutlicht.

Ein Journal in einem Frame und in einem NavigationWindow

Dies ermöglicht es Ihnen, Navigationsunterstützung direkt für sie zu programmieren. Ziehen Sie dies in Erwägung, wenn Sie eine benutzerdefinierte Navigations-UI für einen Frame bereitstellen müssen, der in einem Window gehostet wird. Darüber hinaus implementieren beide Typen zusätzliche Member, die für die Navigation erforderlich sind, einschließlich BackStack (NavigationWindow.BackStack, Frame.BackStack) und ForwardStack (NavigationWindow.ForwardStack, Frame.ForwardStack), mit denen Sie die Journaleinträge im Rückwärts- bzw. Vorwärtsstapel auflisten können.

Wie bereits erwähnt, können in einer Anwendung mehrere Journale vorhanden sein. Die folgende Abbildung enthält ein Beispiel für die Fälle, in denen das auftreten kann.

Mehrere Journale in einer Anwendung

In diesem Thema wurden Page und Paket-XBAPs dazu verwendet, die verschiedenen Navigationsfunktionen von WPF zu veranschaulichen. Eine Page, die in eine Anwendung kompiliert wird, ist nicht die einzige Art von Inhalt, zu der navigiert werden kann. Paket-XBAPs sind nicht die einzige Möglichkeit zum Identifizieren von Inhalt.

Wie in diesem Abschnitt veranschaulicht wird, können Sie auch zu Loose XAML-Dateien, HTML-Dateien und Objekten navigieren.

Unter einer Loose XAML-Datei versteht man eine Datei mit den folgenden Eigenschaften:

  • Enthält nur XAML (d. h., keinen Code).

  • Verfügt über eine entsprechende Namespacedeklaration.

  • Hat die Dateinamenerweiterung .xaml.

Stellen Sie sich z. B. den folgenden, zu speichernden Inhalt als Loose XAML-Datei Person.xaml vor.

<!-- Person.xaml -->
<TextBlock xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation">
  <TextBlock FontWeight="Bold">Name:</TextBlock>
  <TextBlock>Nancy Davolio</TextBlock>
  <LineBreak />
  <TextBlock FontWeight="Bold">Favorite Color:</TextBlock>
  <TextBlock>Yellow</TextBlock>
</TextBlock>

Wenn Sie auf die Datei doppelklicken, wird der Browser geöffnet und navigiert zur Datei und zeigt den Inhalt an. Das wird in der folgenden Abbildung gezeigt.

Anzeige des Inhalts in der Datei Person.XAML.

Sie können eine Loose XAML-Datei von folgenden Orten aus anzeigen:

  • Einer Website auf dem lokalen Computer, dem Intranet oder dem Internet

  • Einer Universal Naming Convention (UNC)-Dateifreigabe

  • Dem lokalen Datenträger

Eine Loose XAML-Datei kann den Favoriten des Browsers hinzugefügt werden oder die Homepage des Browsers darstellen.

HinweisHinweis

Weitere Informationen zum Veröffentlichen und Starten von Loose XAML-Seiten finden Sie unter Bereitstellen von WPF-Anwendungen (WPF).

Loose XAML ist dahingehend eingeschränkt, dass nur Inhalt gehostet werden kann, der zum Ausführen mit teilweiser Vertrauenswürdigkeit sicher ist. Beispielsweise kann Window nicht das Stammelement einer Loose XAML-Datei sein. Weitere Informationen finden Sie unter WPF-Sicherheit mit teilweiser Vertrauenswürdigkeit.

Wie erwartet, können Sie auch zu HTML navigieren. Sie müssen lediglich einen URI zur Verfügung stellen, der das http-Schema verwendet. In der folgenden XAML wird beispielsweise Frame angezeigt, der zu einer HTML-Seite navigiert.

<Frame Source="https://www.microsoft.com/default.aspx" />

Zum Navigieren zu HTML sind besondere Berechtigungen erforderlich. Sie können z. B. nicht von einer XBAP navigieren, die im teilweise vertrauenswürdigen Sicherheitsbereich (Sandbox) der Internetzone ausgeführt wird. Weitere Informationen finden Sie unter WPF-Sicherheit mit teilweiser Vertrauenswürdigkeit.

Das WebBrowser-Steuerelement unterstützt das HTML-Dokumenthosting, die Navigation und die Interoperabilität Skript/verwalteter Code. Ausführliche Informationen zum WebBrowser-Steuerelement finden Sie im WebBrowser.

Wie im Falle von Frame, sind für die Navigation zu HTML unter Verwendung von WebBrowser spezielle Berechtigungen erforderlich. Von einer teilweise vertrauenswürdigen Anwendung können Sie nur zu HTML navigieren, das auf der Ursprungssite gespeichert ist. Weitere Informationen finden Sie unter WPF-Sicherheit mit teilweiser Vertrauenswürdigkeit.

Wenn Sie Daten als benutzerdefinierte Objekte gespeichert haben, können die Daten u. a. durch Erstellen von Page mit Inhalt angezeigt werden, der an diese Objekte gebunden wird (siehe Übersicht über Datenbindung). Wenn Sie eine ganze Seite nicht nur zu dem Zweck erstellen möchten, die Objekte anzuzeigen, können Sie stattdessen direkt zu ihnen navigieren.

Betrachten Sie die im folgenden Code implementierte Person-Klasse.


Namespace SDKSample
    Public Class Person
        Private _name As String
        Private _favoriteColor As Color

        Public Sub New()
        End Sub
        Public Sub New(ByVal name As String, ByVal favoriteColor As Color)
            Me._name = name
            Me._favoriteColor = favoriteColor
        End Sub

        Public Property Name() As String
            Get
                Return Me._name
            End Get
            Set(ByVal value As String)
                Me._name = value
            End Set
        End Property

        Public Property FavoriteColor() As Color
            Get
                Return Me._favoriteColor
            End Get
            Set(ByVal value As Color)
                Me._favoriteColor = value
            End Set
        End Property
    End Class
End Namespace
using System.Windows.Media; // Color

namespace SDKSample
{
    public class Person
    {
        string name;
        Color favoriteColor;

        public Person() { }
        public Person(string name, Color favoriteColor)
        {
            this.name = name;
            this.favoriteColor = favoriteColor;
        }

        public string Name
        {
            get { return this.name; }
            set { this.name = value; }
        }

        public Color FavoriteColor
        {
            get { return this.favoriteColor; }
            set { this.favoriteColor = value; }
        }
    }
}

Rufen Sie die NavigationWindow.Navigate-Methode auf, um zu ihr zu navigieren, wie mit dem folgenden Code veranschaulicht.

<Page 
  xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
  x:Class="SDKSample.HomePage"
  WindowTitle="Page that Navigates to an Object">


...


<Hyperlink Name="hyperlink" Click="hyperlink_Click">
  Navigate to Nancy Davolio
</Hyperlink>


...


</Page>

Namespace SDKSample
    Partial Public Class HomePage
        Inherits Page
        Public Sub New()
            InitializeComponent()
        End Sub

        Private Sub hyperlink_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
            Dim person As New Person("Nancy Davolio", Colors.Yellow)
            Me.NavigationService.Navigate(person)
        End Sub
    End Class
End Namespace
using System.Windows; // RoutedEventArgs
using System.Windows.Controls; // Page
using System.Windows.Media; // Colors

namespace SDKSample
{
    public partial class HomePage : Page
    {
        public HomePage()
        {
            InitializeComponent();
        }

        void hyperlink_Click(object sender, RoutedEventArgs e)
        {
            Person person = new Person("Nancy Davolio", Colors.Yellow);
            this.NavigationService.Navigate(person);
        }
    }
}

In der folgenden Abbildung wird das Ergebnis dargestellt.

Eine Seite, die zu einer Klasse navigiert

Aus dieser Abbildung können Sie ersehen, dass nichts Nützliches angezeigt wird. Tatsächlich handelt es sich beim angezeigten Wert um den Rückgabewert der ToString-Methode für das Person-Objekt. Standardmäßig ist das der einzige Wert, den WPF zum Darstellen des Objekts verwenden kann. Sie könnten die ToString-Methode überschreiben, um aussagekräftigere Informationen zu erhalten. Allerdings wird auch dann nur ein Zeichenfolgenwert zurückgegeben. Mit einer Datenvorlage lassen sich die Darstellungsfunktionen von WPF nutzen. Sie können eine Datenvorlage implementieren, die WPF dem Objekt eines bestimmten Typs zuordnen kann. Im folgenden Code wird eine Datenvorlage für das Person-Objekt gezeigt.

<Application
    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:SDKSample" 
    x:Class="SDKSample.App"
    StartupUri="HomePage.xaml">

  <Application.Resources>

    <!-- Data Template for the Person Class -->
    <DataTemplate DataType="{x:Type local:Person}">
      <TextBlock xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation">
        <TextBlock FontWeight="Bold">Name:</TextBlock>
        <TextBlock Text="{Binding Path=Name}" />
        <LineBreak />
        <TextBlock FontWeight="Bold">Favorite Color:</TextBlock>
        <TextBlock Text="{Binding Path=FavoriteColor}" />
      </TextBlock>
    </DataTemplate>

  </Application.Resources>

</Application>

In diesem Fall wird die Datenvorlage dem Person-Typ unter Verwendung der x:Type-Markuperweiterung im DataType-Attribut zugeordnet. Die Datenvorlage bindet dann TextBlock-Elemente (siehe TextBlock) an die Eigenschaften der Person-Klasse. In der folgenden Abbildung wird die aktualisierte Darstellung des Person-Objekts angezeigt.

Navigation zu einer Klasse mit einer Datenvorlage

Ein Vorteil dieser Technik liegt in der Konsistenz, die Ihnen die Wiederverwendung der Datenvorlage zur konsistenten Anzeige Ihrer Objekte in der gesamten Anwendung erlaubt.

Weitere Informationen zu Datenvorlagen finden Sie unter Übersicht über Datenvorlagen.

Sicherheit

Die WPF-Navigationsunterstützung ermöglicht es, dass über das Internet zu XBAPs navigiert werden kann. Außerdem können Anwendungen Inhalt von Drittanbietern hosten. Um Benutzer und Anwendungen vor bedrohlichem Verhalten zu schützen, stellt WPF eine Palette an Sicherheitsfeatures bereit, die unter Sicherheit (WPF) und WPF-Sicherheit mit teilweiser Vertrauenswürdigkeit behandelt werden.

Siehe auch

Referenz

SetCookie

GetCookie

Konzepte

Übersicht über die Anwendungsverwaltung

Paket-URI in WPF

Übersicht über die strukturierte Navigation

Übersicht über Navigationstopologien

Bereitstellen von WPF-Anwendungen (WPF)

Weitere Ressourcen

Gewusst-wie-Themen zur Navigation