Freigeben über


Navigationsübersicht

Windows Presentation Foundation (WPF) unterstützt browserbasierte Navigation, die in zwei Arten von Anwendungen verwendet werden kann: eigenständige Anwendungen und XAML-Browseranwendungen (XBAPs). Um Inhalte für die Navigation zu verpacken, stellt WPF die Page Klasse bereit. Sie können deklarativ von einem Page zu einem anderen navigieren, indem Sie ein Hyperlink, oder programmgesteuert mithilfe der NavigationService. WPF verwendet das Journal, um Seiten zu merken, von denen navigiert wurde, und um zurück zu ihnen zu navigieren.

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

Hinweis

In diesem Thema bezieht sich der Begriff "Browser" nur auf Browser, die WPF-Anwendungen hosten können, die derzeit Microsoft Internet Explorer und Firefox enthalten. Wenn bestimmte WPF-Features nur von einem bestimmten Browser unterstützt werden, wird auf die Browserversion verwiesen.

Dieses Thema enthält eine Übersicht über die wichtigsten Navigationsfunktionen in WPF. Diese Funktionen sind sowohl für eigenständige Anwendungen als auch für XBAPs verfügbar, obwohl in diesem Thema diese im Kontext eines XBAP präsentiert werden.

Hinweis

In diesem Thema wird nicht erläutert, wie XBAPs erstellt und bereitgestellt werden. Weitere Informationen zu XBAPs finden Sie in der Übersicht über WPF-XAML-Browseranwendungen.

In diesem Abschnitt werden die folgenden Aspekte der Navigation erläutert und veranschaulicht:

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 enthalten. Sie werden jedoch feststellen, dass die am häufigsten verwendete und bequemste Methode zur Verpackung von Inhalten die Nutzung von Page ist. Darüber hinaus implementiert Page spezifische Navigationsfunktionen, um deren Erscheinungsbild zu verbessern und die Entwicklung zu vereinfachen.

Mithilfe von Page können Sie eine navigierbare Seite mit XAML-Inhalten deklarativ implementieren, indem Sie Markup wie das folgende verwenden.

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

Ein in XAML-Markup implementiertes Page hat 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 Eigenschaftselement festlegen, wie im folgenden Markup gezeigt.

<Page xmlns="http://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 ist der Inhalt eine einzelne Zeichenfolge, "Hello, Page!" In der Praxis verwenden Sie in der Regel ein Layoutsteuerelement als untergeordnetes Element (siehe Layout), um Ihre Inhalte zu enthalten und zu verfassen.

Die untergeordneten Elemente eines Page Elements werden als Inhalt eines Page Elements betrachtet und daher müssen Sie die explizite Page.Content Deklaration nicht verwenden. Das folgende Markup ist das deklarative Äquivalent zum vorherigen Beispiel.

<Page xmlns="http://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 gesetzt. Weitere Informationen finden Sie im WPF-Inhaltsmodell.

Ein reines Markup ist nur zum Anzeigen von Inhalten nützlich. Eine Page Kann jedoch auch Steuerelemente anzeigen, mit denen Benutzer mit der Seite interagieren können, und sie kann auf Benutzerinteraktionen reagieren, indem Ereignisse behandelt und Anwendungslogik aufgerufen wird. Ein interaktives Page-Objekt wird mithilfe einer Kombination aus Markup und Code-Behind implementiert, wie im folgenden Beispiel gezeigt.

<Page
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="SDKSample.HomePage">
  Hello, from the XBAP HomePage!
</Page>
using System.Windows.Controls;

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

Imports System.Windows.Controls

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

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

  • Im Markup muss das Page-Element das attribut x:Class enthalten. Beim Erstellen der Anwendung führt das Vorhandensein von x:Class in der Markupdatei, die von einer Microsoft Build Engine (MSBuild) erstellt wird, dazu, dass eine partial-Klasse erstellt wird, die von Page abgeleitet wird und den durch das x:Class-Attribut festgelegten Namen erhält. Dies erfordert das Hinzufügen einer XML-Namespacedeklaration für das XAML-Schema ( xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" ). Die generierte partial Klasse implementiert InitializeComponent, das aufgerufen wird, um die Ereignisse zu registrieren und die Eigenschaften festzulegen, die im Markup implementiert werden.

  • Bei CodeBehind 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 sein. Auf diese Weise kann die CodeBehind-Datei mit der partial-Klasse verknüpft werden, die beim Erstellen der Anwendung (siehe Erstellen einer WPF-Anwendung) 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.

Hinweis

Wenn Sie ein neues Page zu Ihrem Projekt mithilfe von Visual Studio hinzufügen, wird die Page Implementierung mit Markup und Code-Behind realisiert und enthält die notwendige Konfiguration zur Zuordnung zwischen Markup- und Code-Behind-Dateien, wie hier beschrieben.

Sobald Sie eine Pagehaben, können Sie zu ihr navigieren. Um den Ersten Page anzugeben, zu dem eine Anwendung navigiert, müssen Sie den Start Pagekonfigurieren.

Konfigurieren einer Startseite

XBAPs erfordern eine bestimmte Menge an Anwendungsinfrastruktur, die in einem Browser gehostet werden muss. In WPF ist die Application Klasse Teil einer Anwendungsdefinition, die die erforderliche Anwendungsinfrastruktur festlegt (siehe Anwendungsverwaltungsübersicht).

Eine Anwendungsdefinition wird in der Regel mithilfe von Markup und CodeBehind implementiert, wobei die Markupdatei als MSBuild-ElementApplicationDefinition konfiguriert ist. Es folgt eine Anwendungsdefinition für eine XBAP.

<Application
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="SDKSample.App" />
using System.Windows;

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

Imports System.Windows

Namespace SDKSample
    Partial Public Class App
        Inherits Application
    End Class
End Namespace

Ein XBAP kann seine Anwendungsdefinition verwenden, um einen Startpunkt Page anzugeben, der Page automatisch geladen wird, wenn das XBAP gestartet wird. Dazu legen Sie die Eigenschaft StartupUri mit dem Uniform Resource Identifier (URI) für den gewünschten Page fest.

Hinweis

In den meisten Fällen wird die Page entweder in eine Anwendung kompiliert oder mit einer Anwendung bereitgestellt. In diesen Fällen ist der URI, der einen Page als pack URI identifiziert, ein URI, der dem Paketschema entspricht. Pack-URIs werden in Pack-URIs in WPF weiter erläutert. Sie können auch mithilfe des http-Schemas zu Inhalten navigieren, das unten erläutert wird.

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

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

In diesem Beispiel wird das StartupUri Attribut mit einem relativer Pack-URI festgelegt, die HomePage.xaml identifiziert. Wenn der XBAP gestartet wird, wird "HomePage.xaml" automatisch aufgerufen und angezeigt. Dies wird durch die folgende Abbildung veranschaulicht, die einen XBAP zeigt, der von einem Webserver gestartet wurde.

XBAP-Seite

Hinweis

Weitere Informationen zur Entwicklung und Bereitstellung von XBAPs finden Sie unter WPF XAML Browser Applications Overview and Deploying a WPF Application.

Konfigurieren des Titels, der Breite und der Höhe des Hostfensters

Möglicherweise haben Sie aus der vorherigen Abbildung bemerkt, dass der Titel des Browsers und des Registerkartenbereichs der URI für XBAP ist. Neben der langen Länge ist der Titel weder attraktiv noch informativ. Aus diesem Grund bietet Page Ihnen die Möglichkeit, den Titel zu ändern, indem Sie die WindowTitle-Eigenschaft festlegen. Darüber hinaus können Sie die Breite und Höhe des Browserfensters konfigurieren, indem Sie WindowWidth und WindowHeight jeweils festlegen.

WindowTitle, WindowWidthund WindowHeight kann deklarativ im Markup festgelegt werden, wie im folgenden Beispiel gezeigt.

<Page
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://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 ist in der folgenden Abbildung dargestellt.

Fenstertitel, Höhe, Breite

Ein typischer XBAP besteht aus mehreren Seiten. Die einfachste Möglichkeit, von einer Seite zu einer anderen zu navigieren, ist die Verwendung einer Hyperlink. Sie können einem Element Hyperlink deklarativ einen Page hinzufügen, indem Sie das Hyperlink Element verwenden, das im folgenden Markup angezeigt wird.

<Page
  xmlns="http://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>

Ein Hyperlink Element erfordert Folgendes:

  • Der Pack-URI des Page zu navigierenden Pakets, wie durch das NavigateUri Attribut angegeben.

  • Inhalt, auf den ein Benutzer klicken kann, um die Navigation zu initiieren, z. B. Text und Bilder (für den Inhalt, den das Hyperlink Element enthalten kann, siehe Hyperlink).

In der folgenden Abbildung ist ein XBAP mit einer Page XBAP dargestellt, die ein Hyperlink.

Seite mit Link

Wie Sie erwarten würden, klicken Sie auf die Hyperlink Ursachen, die die XBAP zu dem Page durch das NavigateUri Attribut identifizierten Navigiert. Zusätzlich wird durch den XBAP ein Eintrag für die vorherige Page zur Liste der zuletzt aufgerufenen Seiten in Internet Explorer hinzugefügt. Das wird in der folgenden Abbildung gezeigt.

Schaltflächen

Die Fragmentnavigation wird ebenso unterstützt wie die Navigation von einem Page zu einem anderen Hyperlink.

Fragmentnavigation

Fragmentnavigation ist die Navigation zu einem Inhaltsfragment im aktuellen Page oder einem anderen Page. In WPF ist ein Inhaltsfragment der Inhalt, der in einem benannten Element enthalten ist. Ein benanntes Element ist ein Element, das seinen Name Attributsatz aufweist. Das folgende Markup zeigt ein benanntes TextBlock Element, das ein Inhaltsfragment enthält.

<Page
    xmlns="http://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 Inhaltsfragment navigieren kann, muss das NavigateUri Attribut Folgendes enthalten:

  • Der URI des Page Inhaltsfragments, zu dem navigiert werden soll.

  • Ein "#"-Zeichen.

  • Der Name des Elements auf dem Page, das das Inhaltsfragment enthält.

Ein Fragment-URI weist das folgende Format auf.

PageURI#ElementName

Das folgende Beispiel zeigt ein Hyperlink, das so konfiguriert ist, dass es zu einem Inhaltsfragment navigiert.

<Page
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  WindowTitle="Page That Navigates To Fragment" >
<Hyperlink NavigateUri="PageWithFragments.xaml#Fragment1">
  Navigate To pack Fragment
</Hyperlink>
</Page>

Hinweis

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

Von Bedeutung

Sie können nur zu Fragmenten auf losen XAML-Seiten (nur-Markup-XAML-Dateien mit Page als Stammelement) navigieren, wenn die Seiten über HTTP durchsucht werden können.

Eine lose XAML-Seite kann jedoch zu ihren eigenen Fragmenten navigieren.

Hyperlink ermöglicht es einem Benutzer, die Navigation zu einem bestimmten Page zu initiieren, während die Suche und das Herunterladen der Seite von der NavigationService Klasse ausgeführt werden. Im Wesentlichen bietet NavigationService die Möglichkeit, im Auftrag von Clientcode eine Navigationsanforderung zu verarbeiten, wie z. B. Hyperlink. Darüber hinaus implementiert NavigationService Unterstützung auf höherer Ebene zur Nachverfolgung und Einflussnahme auf eine Navigationsanfrage.

Wenn auf Hyperlink geklickt wird, ruft WPF NavigationService.Navigate auf, um den Pack-URI Page zu lokalisieren und herunterzuladen. Das heruntergeladene Page Objekt wird in eine Struktur von Objekten konvertiert, deren Stammobjekt eine Instanz des heruntergeladenen PageObjekts ist. Ein Verweis auf das Stammobjekt Page wird in der NavigationService.Content Eigenschaft gespeichert. Der Pack-URI für den Inhalt, zu dem navigiert wurde, wird in der NavigationService.Source Eigenschaft gespeichert, während der NavigationService.CurrentSource Pack-URI für die letzte Seite gespeichert wird, zu der navigiert wurde.

Hinweis

Es ist möglich, dass eine WPF-Anwendung mehr als eine aktuell aktiv NavigationServiceist. Weitere Informationen finden Sie weiter unten in diesem Thema unter Navigationshosts .

Programmgesteuerte Navigation mit dem Navigationsdienst

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

Es gibt jedoch Situationen, in denen Sie direkt verwenden NavigationService müssen, einschließlich der folgenden:

  • Wenn Sie einen Page mit einem Konstruktor ohne Parameter instanziieren müssen.

  • Wenn Sie Eigenschaften auf dem Page festlegen müssen, bevor Sie zu ihm/ihr navigieren.

  • Wenn der Page erst zur Laufzeit bestimmt werden kann, zu dem navigiert werden muss.

In diesen Situationen müssen Sie Code schreiben, um die Navigation programmgesteuert zu initiieren, indem Sie die Navigate Methode des NavigationService Objekts aufrufen. Dafür ist ein Verweis auf ein NavigationService erforderlich.

Abrufen einer Referenz auf den NavigationService

Aus Gründen, die im Abschnitt "Navigationshosts " behandelt werden, kann eine WPF-Anwendung mehrere NavigationServiceaufweisen. Dies bedeutet, dass Ihr Code eine Möglichkeit benötigt, um eine NavigationService zu finden, in der Regel die NavigationService, die zum aktuellen Page navigiert. Sie können einen Verweis auf ein NavigationService Objekt abrufen, indem Sie die staticNavigationService.GetNavigationService Methode aufrufen. Um das NavigationService Objekt abzurufen, das zu einem bestimmten PageObjekt navigiert wurde, übergeben Sie einen Verweis auf das Page Argument der GetNavigationService Methode. Der folgende Code zeigt, wie Sie den NavigationService für den aktuellen Page abrufen.

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

Als Abkürzung für das Finden von NavigationService für ein Page implementiert Page die Eigenschaft NavigationService. Dies wird im folgenden Beispiel gezeigt.

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

Hinweis

Ein Page kann nur einen Verweis auf sein NavigationService erhalten, wenn Page das Loaded Ereignis auslöst.

Programmgesteuerte Navigation zu einem Page-Objekt

Das folgende Beispiel zeigt, wie Sie mithilfe der NavigationService programmatisch zu einem Page navigieren können. Die programmgesteuerte Navigation ist erforderlich, da die Navigation, zu der Page navigiert wird, nur mithilfe eines einzelnen, nicht parameterlosen Konstruktors instanziiert werden kann. Der Page, der einen Konstruktor ohne Parameter besitzt, wird im folgenden Markup und Code dargestellt.

<Page
    x:Class="SDKSample.PageWithNonDefaultConstructor"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="PageWithNonDefaultConstructor">
  
  <!-- Content goes here -->
  
</Page>
using System.Windows.Controls;

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

            this.Content = message;
        }
    }
}

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

Der Page, der zur Page mit dem nicht-parameterlosen Konstruktor navigiert, wird im folgenden Markup und Code gezeigt.

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

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

</Page>
using System.Windows;
using System.Windows.Controls;
using System.Windows.Navigation;

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);
        }
    }
}

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

Wenn auf diese HyperlinkPage Option geklickt wird, wird die Navigation durch Instanziieren der Page Navigation zum Verwenden des nicht parameterlosen Konstruktors und Aufrufen der NavigationService.Navigate Methode initiiert. Navigate akzeptiert einen Verweis auf das Objekt, zu dem mit NavigationService navigiert wird, statt zu einem Pack-URI.

Programmnavigation mit einer Pack-URI

Wenn Sie einen Pack-URI programmgesteuert erstellen müssen (wenn Sie den Pack-URI nur zur Laufzeit ermitteln können), können Sie die NavigationService.Navigate Methode verwenden. Dies wird im folgenden Beispiel gezeigt.

<Page
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="SDKSample.NSUriNavigationPage">
  <Hyperlink Click="hyperlink_Click">Navigate to Page by Pack URI</Hyperlink>
</Page>
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Navigation;

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);
        }
    }
}

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

Aktualisieren der aktuellen Seite

A Page wird nicht heruntergeladen, wenn er den gleichen Pack-URI wie der Pack-URI aufweist, der in der NavigationService.Source Eigenschaft gespeichert ist. Um das erneute Herunterladen der aktuellen Seite zu erzwingen, können Sie die Methode NavigationService.Refresh aufrufen, wie im folgenden Beispiel gezeigt.

<Page
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="SDKSample.NSRefreshNavigationPage">
 <Hyperlink Click="hyperlink_Click">Refresh this page</Hyperlink>
</Page>
using System.Windows;
using System.Windows.Controls;
using System.Windows.Navigation;

namespace SDKSample
{
    public partial class NSRefreshNavigationPage : Page
    {

Namespace SDKSample
    Partial Public Class NSRefreshNavigationPage
        Inherits Page
        void hyperlink_Click(object sender, RoutedEventArgs e)
        {
            // Force WPF to download this page again
            this.NavigationService.Refresh();
        }
    }
}
        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

Es gibt viele Möglichkeiten, die Navigation zu initiieren, wie Sie gesehen haben. Wenn die Navigation initiiert wird und während die Navigation ausgeführt wird, können Sie die Navigation mithilfe der folgenden Ereignisse nachverfolgen und beeinflussen, die von NavigationService:

  • Navigating. Tritt auf, wenn eine neue Navigation angefordert wird. Kann verwendet werden, um die Navigation abzubrechen.

  • NavigationProgress. Tritt in regelmäßigen Abständen während eines Downloads auf, um Navigationsfortschrittsinformationen bereitzustellen.

  • Navigated. Tritt auf, wenn die Seite gefunden und heruntergeladen wurde.

  • NavigationStopped. Tritt auf, wenn die Navigation beendet wird (durch Aufrufen StopLoading), oder wenn eine neue Navigation angefordert wird, während eine aktuelle Navigation ausgeführt wird.

  • NavigationFailed. Tritt auf, wenn beim Navigieren zum angeforderten Inhalt ein Fehler ausgelöst wird.

  • LoadCompleted. Tritt auf, wenn Inhalte, zu denen navigiert wurde, geladen und analysiert werden und mit dem Rendern begonnen haben.

  • FragmentNavigation. Tritt auf, wenn die Navigation zu einem Inhaltsfragment beginnt, was geschieht:

    • Unmittelbar, wenn sich das gewünschte Fragment im aktuellen Inhalt befindet.

    • Nachdem der Quellinhalt geladen wurde, falls 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.

Seitennavigationsflussdiagramm

Im Allgemeinen macht sich Page keine Sorgen über diese Ereignisse. Es ist wahrscheinlicher, dass sich eine Anwendung mit ihnen beschäftigt, und aus diesem Grund werden diese Ereignisse auch von der Application Klasse ausgelöst:

Jedes Mal, wenn NavigationService ein Ereignis ausgelöst wird, löst die Application Klasse das entsprechende Ereignis aus. Frame und NavigationWindow bieten dieselben Ereignisse an, um die Navigation innerhalb ihrer jeweiligen Bereiche zu erkennen.

In einigen Fällen könnte ein Page Interesse an diesen Ereignissen haben. Beispielsweise könnte ein Page das NavigationService.Navigating-Ereignis behandeln, um zu bestimmen, ob die Navigation von sich selbst abgebrochen werden sollte. Dies wird im folgenden Beispiel gezeigt.

<Page
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="SDKSample.CancelNavigationPage">
  <Button Click="button_Click">Navigate to Another Page</Button>
</Page>
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Navigation;

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;
        }
    }
}

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

Wenn Sie einen Handler mit einem Navigationsereignis aus einem Page registrieren, wie dies im vorherigen Beispiel der Fall ist, müssen Sie auch den Ereignishandler abmelden. Wenn Sie es nicht tun, kann es Nebeneffekte in Bezug darauf geben, wie die WPF-Navigation mithilfe des Journals Page die Navigation speichert.

Erinnern der Navigation mit dem Journal

WPF verwendet zwei Stapel, um die Seiten zu merken, von denen Sie navigiert haben: ein Zurück-Stapel und ein Vorwärtsstapel. Wenn Sie von der aktuellen Page zu einer neuen Page oder vorwärts zu einem vorhandenen Page navigieren, wird die aktuelle Page dem Rückstapel hinzugefügt. Wenn Sie vom aktuellen Page zurück zum vorherigen Page navigieren, wird das aktuelle Page dem Vorwärtsstapel hinzugefügt. Der Hintergrundstapel, der Vorwärtsstapel und die Funktionalität zum Verwalten dieser Stapel werden gemeinsam als Journal bezeichnet. Jedes Element im Hintergrundstapel und der Vorwärtsstapel ist eine Instanz der JournalEntry Klasse und wird als Journaleintrag bezeichnet.

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

Schaltflächen

Für XBAPs, die von Internet Explorer gehostet werden, integriert WPF das Journal in die Navigationsoberfläche von Internet Explorer. Auf diese Weise können Benutzer mithilfe der Schaltflächen " Zurück", " Vorwärts" und " Zuletzt verwendete Seiten " in Internet Explorer in einem XBAP navigieren.

Von Bedeutung

Wenn ein Benutzer in Internet Explorer von und zurück zu einem XBAP navigiert, werden nur die Journaleinträge für Seiten, die nicht am Leben gehalten wurden, im Journal aufbewahrt. Weitere Informationen zum Lebendighalten von Seiten finden Sie unter "Seitenlebensdauer" und "Journal " weiter unten in diesem Thema.

Standardmäßig ist der Text für jeden Page Text, der in der Liste "Zuletzt verwendete Seiten " von Internet Explorer angezeigt wird, der URI für die Page. In vielen Fällen ist dies für den Benutzer nicht besonders sinnvoll. Glücklicherweise können Sie den Text mit einer der folgenden Optionen ändern:

  1. Der Wert des angefügten JournalEntry.Name Attributs.

  2. Der Page.Title Attributwert.

  3. Der Attributwert des Page.WindowTitle und die URI des aktuellen Page.

  4. Der URI für den aktuellen Page. (Standard)

Die Reihenfolge, in der die Optionen aufgelistet werden, entspricht der Reihenfolge der Rangfolge zum Suchen des Texts. Wenn beispielsweise JournalEntry.Name festgelegt wird, werden die anderen Werte ignoriert.

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

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

namespace SDKSample
{
    public partial class PageWithTitle : Page
    {

Namespace SDKSample
    Partial Public Class PageWithTitle
        Inherits Page
    }
}
    End Class
End Namespace

Obwohl ein Benutzer mithilfe der Seiten "Zurück", " Vorwärts" und " Zuletzt verwendete Seiten " in Internet Explorer im Journal navigieren kann, können Sie auch mithilfe deklarativer und programmgesteuerter Mechanismen navigieren, die von WPF bereitgestellt werden. Ein Grund hierfür ist die Bereitstellung von benutzerdefinierten Navigations-UIs auf Ihren Seiten.

Sie können deklarativ Unterstützung für die Journalnavigation hinzufügen, indem Sie die Navigationsbefehle verwenden, die von NavigationCommands bereitgestellt werden. Im folgenden Beispiel wird die Verwendung des BrowseBack Navigationsbefehls veranschaulicht.

<Page
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://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 im Journal navigieren, indem Sie eines der folgenden Member der NavigationService Klasse verwenden:

Das Journal kann auch programmgesteuert bearbeitet werden, wie in der Aufbewahrung des Inhaltszustands mit navigationsverlauf weiter unten in diesem Thema beschrieben.

Lebensdauer einer Seite und Journal

Erwägen Sie eine XBAP mit mehreren Seiten, die umfangreiche Inhalte enthalten, einschließlich Grafiken, Animationen und Medien. Der Speicherbedarf für Seiten wie diese könnte recht groß sein, insbesondere, wenn Video- und Audiomedien verwendet werden. Angesichts der Tatsache, dass das Journal "merkt" Seiten, zu denen navigiert wurde, könnte ein solcher XBAP schnell eine große und spürbare Menge an Arbeitsspeicher verbrauchen.

Aus diesem Grund besteht das Standardverhalten des Journals darin, Metadaten in jedem Journaleintrag anstelle eines Verweises auf ein Page Objekt zu speichernPage. Wenn ein Journaleintrag aufgerufen wird, werden seine Page Metadaten verwendet, um eine neue Instanz der angegebenen Page zu erstellen. Daher hat jedes navigierte Page die Lebensdauer, die in der folgenden Abbildung dargestellt wird.

Die Seitenlebensdauer

Obwohl die Verwendung der Standardeinstellungen für das Journaling den Speicherverbrauch verringern kann, kann die Leistung beim Seiten-Rendering reduziert werden. Eine Neuinstanzierung von Page kann zeitintensiv sein, insbesondere, wenn Page viele Inhalte enthält. Wenn Sie eine Page Instanz im Journal beibehalten müssen, können Sie auf zwei Techniken zurückgreifen. Zunächst können Sie programmgesteuert zu einem Page Objekt navigieren, indem Sie die NavigationService.Navigate Methode aufrufen.

Zweitens können Sie angeben, dass WPF eine Instanz eines Page im Journal beibehalten soll, indem Sie die KeepAlive-Eigenschaft auf true festlegen (Standard ist false). Wie im folgenden Beispiel gezeigt, können Sie im Markup deklarativ festlegen KeepAlive .

<Page
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://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 eines aufrechterhaltenen Page unterscheidet sich leicht von der eines Page, das nicht aufrechterhalten wird. Das erste Mal, wenn ein Page am Leben gehalten wird, wird es instanziiert, genau wie ein Page, der nicht am Leben gehalten wird. Da jedoch eine Instanz der Page im Journal aufbewahrt wird, wird sie nie wieder instanziiert, solange sie im Journal verbleibt. Wenn eine Page eine Initialisierungslogik enthält, die jedes Mal ausgeführt werden muss, wenn zu Page navigiert wird, sollten Sie diese vom Konstruktor in einen Handler für das Loaded Ereignis verschieben. Wie in der folgenden Abbildung dargestellt, werden die Loaded-Ereignisse weiterhin jedes Mal ausgelöst, wenn zu einem Unloaded navigiert wird oder von diesem weg.

Wenn die Ereignisse ,

Wenn eine Page nicht am Leben gehalten wird, sollten Sie keine der folgenden Maßnahmen ausführen:

  • Speichern Sie einen Verweis darauf oder einen Teil davon.

  • Registrieren Sie Ereignishandler für Ereignisse, die nicht von ihr implementiert werden.

Wenn Sie eine dieser Aktionen ausführen, werden Verweise erstellt, die erzwingen, dass die Page im Arbeitsspeicher erhalten bleibt, auch nachdem sie aus dem Journal entfernt wurde.

Im Allgemeinen sollten Sie das Standardverhalten Page bevorzugen, bei dem Page nicht am Leben erhalten wird. Dies hat jedoch staatliche Auswirkungen, die im nächsten Abschnitt erläutert werden.

Beibehalten des Inhaltsstatus mit Navigationshistorie

Wenn ein Page Objekt nicht am Leben erhalten wird und über Benutzerelemente verfügt, die Daten vom Benutzer sammeln, was passiert mit den Daten, wenn ein Benutzer die Seite verlässt und dann zum Page zurückkehrt? Aus Sicht der Benutzererfahrung sollte der Benutzer erwarten, dass die zuvor eingegebenen Daten angezeigt werden. Leider wird mit jeder Navigation eine neue Instanz von Page erstellt, wodurch die Steuerelemente, die die Daten gesammelt hatten, neu initialisiert werden und die Daten verloren gehen.

Glücklicherweise bietet das Journal Unterstützung für das Speichern von Daten über Page hinweg, einschließlich Steuerdaten. Insbesondere fungiert der Journaleintrag für jeden Page als temporärer Container für den zugeordneten Page Zustand. In den folgenden Schritten wird beschrieben, wie diese Unterstützung genutzt wird, wenn von einer Page weg navigiert wird:

  1. Dem Journal wird ein Eintrag für den aktuellen Page hinzugefügt.

  2. Der Status von Page wird mit dem Journaleintrag für diese Seite gespeichert, der dem Backstack hinzugefügt wird.

  3. Zu der neuen Page wird navigiert.

Wenn mithilfe des Journals zurück zur Seite Page navigiert wird, treten die folgenden Schritte ein:

  1. Der Page (oberste Journaleintrag im Hintergrundstapel) wird instanziiert.

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

  3. Zu Page wird zurück navigiert.

WPF verwendet diese Funktionalität automatisch, wenn die folgenden Steuerelemente in einem Page verwendet werden:

Wenn ein Page diese Steuerelemente verwendet, werden die darin eingegebenen Daten über Page Navigationen hinweg gespeichert, wie in der folgenden Abbildung durch die LieblingsfarbeListBox dargestellt.

Seite mit Steuerelementen, die den Zustand speichern

Wenn ein Page andere Steuerelemente als diejenigen in der vorherigen Liste hat oder der Zustand in benutzerdefinierten Objekten gespeichert ist, müssen Sie Code verfassen, um das Journal den Zustand bei Navigationen über Page hinweg merken zu lassen.

Wenn Sie kleine Teile des Zustands über Page-Navigationsvorgänge hinweg speichern müssen, können Sie Abhängigkeitseigenschaften (siehe DependencyProperty) verwenden, die mit dem FrameworkPropertyMetadata.Journal Metadaten-Flag konfiguriert sind.

Wenn der Zustand, den Sie Page in navigationsübergreifenden Navigationen speichern müssen, aus mehreren Datenteilen besteht, kann es weniger codeintensiv sein, ihren Zustand in einer einzigen Klasse zu kapseln und die IProvideCustomContentState Schnittstelle zu implementieren.

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

Cookies

Eine weitere Möglichkeit, wie WPF-Anwendungen Daten speichern können, sind Cookies, die mit den SetCookie- und GetCookie-Methoden erstellt, aktualisiert und gelöscht werden. Die Cookies, die Sie in WPF erstellen können, sind die gleichen Cookies, die andere Arten von Webanwendungen verwenden; Cookies sind beliebige Datenelemente, die von einer Anwendung auf einem Clientcomputer entweder während oder über Anwendungssitzungen gespeichert werden. Cookiedaten werden in der Regel als Name/Wert-Paar im folgenden Format verwendet.

Name=Wert

Wenn die Daten an SetCookie zusammen mit Uri, die den Ort angeben, für den der Cookie erstellt werden soll, übergeben werden, wird ein Cookie im Arbeitsspeicher erstellt, das nur während der aktuellen Anwendungssitzung verfügbar ist. Diese Art von Cookie wird als Sitzungscookies bezeichnet.

Um ein Cookie über Anwendungssitzungen hinweg zu speichern, muss dem Cookie ein Ablaufdatum mit dem folgenden Format hinzugefügt werden.

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

Ein Cookie mit ablaufendem Datum wird im Ordner "Temporäre Internetdateien" der aktuellen Windows-Installation gespeichert, bis das Cookie abläuft. Ein solches Cookie wird als persistentes Cookie bezeichnet, da es über Anwendungssitzungen hinweg beibehalten wird.

Sie rufen sitzungs- und persistente Cookies ab, indem Sie die GetCookie Methode aufrufen und den Uri Speicherort übergeben, an dem das Cookie mit der SetCookie Methode gesetzt wurde.

Im Folgenden finden Sie einige der Möglichkeiten, wie Cookies in WPF unterstützt werden:

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

  • Cookies, die von einem XBAP erstellt werden, können über den Browser aufgerufen werden.

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

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

  • Cookies werden versendet, wenn XBAPs und lose XAML-Seiten Webanforderungen stellen.

  • Sowohl XBAPs auf oberster Ebene als auch XBAPs, die in IFRAMES gehostet werden, können auf Cookies zugreifen.

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

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

Strukturierte Navigation

Wenn Sie Daten von einem Page an einen anderen übergeben müssen, können Sie die Daten als Argumente an einen nicht parameterlosen Konstruktor des Page übergeben. Wenn Sie diese Technik verwenden, müssen Sie Page am Leben erhalten. Wenn nicht, wird beim nächsten Navigieren zu Page WPF Page mit dem parameterlosen Konstruktor neu instanziiert.

Alternativ können Sie Page Eigenschaften implementieren, die mit den Daten definiert werden, die übergeben werden müssen. Die Angelegenheit wird jedoch kompliziert, wenn ein Page Daten an das Page zurückübermitteln muss, das darauf navigiert hat. Das Problem besteht darin, dass die Navigation keine systemeigenen Mechanismen unterstützt, um sicherzustellen, dass ein Page Element zurückgegeben wird, nachdem es navigiert wurde. Im Wesentlichen unterstützt die Navigation keine Anruf-/Rückgabesemantik. Um dieses Problem zu beheben, stellt WPF die PageFunction<T> Klasse bereit, die Sie verwenden können, um sicherzustellen, dass eine Page Zurückgabe in vorhersehbarer und strukturierter Weise erfolgt. Weitere Informationen finden Sie unter "Übersicht über strukturierte Navigation".

Die NavigationWindow-Klasse

Zu diesem Zeitpunkt haben Sie die Bandbreite der Navigationsdienste gesehen, die Sie höchstwahrscheinlich zum Erstellen von Anwendungen mit navigierbarem Inhalt verwenden. Diese Dienste wurden im Zusammenhang mit XBAPs diskutiert, obwohl sie nicht auf XBAPs beschränkt sind. Moderne Betriebssysteme und Windows-Anwendungen nutzen die Browsererfahrung moderner Benutzer, um die Browsernavigation in eigenständige Anwendungen zu integrieren. Häufige Beispiele sind:

  • Word-Thesaurus: Erkunden Sie Wortwahlmöglichkeiten.

  • Datei-Explorer: Navigieren sie in Dateien und Ordnern.

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

Um die Browserformatnavigation in Ihre eigenständigen Anwendungen zu integrieren, können Sie die NavigationWindow Klasse verwenden. NavigationWindow, wird von Window abgeleitet und erweitert es um die gleiche Unterstützung für die Navigation, die XBAPs bereitstellen. Sie können entweder als Hauptfenster Ihrer eigenständigen Anwendung oder als sekundäres Fenster wie z. B. ein Dialogfeld verwenden NavigationWindow .

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

<NavigationWindow
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="SDKSample.MainWindow" 
    Source="HomePage.xaml"/>
using System.Windows.Navigation;

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

Namespace SDKSample
    Partial Public Class MainWindow
        Inherits NavigationWindow
        Public Sub New()
            InitializeComponent()
        End Sub
    End Class
End Namespace

Dieser Code erstellt ein NavigationWindow, das automatisch zu einer Page (HomePage.xaml) navigiert, wenn NavigationWindow geöffnet wird. Wenn es sich NavigationWindow um das Hauptanwendungsfenster handelt, können Sie das StartupUri Attribut verwenden, um es zu starten. Dies wird im folgenden Markup gezeigt.

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

Die folgende Abbildung zeigt das NavigationWindow als das Hauptfenster einer eigenständigen Anwendung.

Ein Hauptfenster

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

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

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

In der Regel implementieren Sie Ihr eigenes NavigationWindow, wenn Sie entweder sein Verhalten oder sein Aussehen anpassen müssen. Wenn Sie keines der beiden Aktionen ausführen, können Sie eine Verknüpfung verwenden. Wenn Sie den Pack-URI eines Page als StartupUri in einer eigenständigen Anwendung angeben, erstellt Application automatisch einen NavigationWindow, um die Page zu hosten. Das folgende Markup zeigt, wie Sie dies aktivieren.

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

Wenn ein sekundäres Anwendungsfenster wie z. B. ein Dialogfeld sein NavigationWindowsoll, können Sie den Code im folgenden Beispiel verwenden, um es zu öffnen.

// 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();
' 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()

Die folgende Abbildung zeigt das erwartete Ergebnis.

Ein Dialogfeld

Wie Sie sehen können, NavigationWindow werden die Schaltflächen "Zurück " und " Vorwärts " im Internet Explorer-Stil angezeigt, mit denen Benutzer im Journal navigieren können. Diese Schaltflächen bieten die gleiche Benutzererfahrung, wie in der folgenden Abbildung dargestellt.

Schaltflächen

Wenn Ihre Seiten eine eigene Journalnavigationsunterstützung und Benutzeroberfläche bereitstellen, können Sie die Schaltflächen Zurück und Vorwärts ausblenden, indem Sie den Wert der NavigationWindow-Eigenschaft auf ShowsNavigationUI setzen.

Alternativ können Sie die Anpassungsunterstützung in WPF verwenden, um die Benutzeroberfläche des NavigationWindow selbst zu ersetzen.

Die Frame-Klasse

Sowohl der Browser als auch NavigationWindow sind Fenster, die navigierbare Inhalte hosten. In einigen Fällen verfügen Anwendungen über Inhalte, die nicht von einem gesamten Fenster gehostet werden müssen. Stattdessen werden solche Inhalte in anderen Inhalten gehostet. Sie können navigierbare Inhalte mithilfe der Frame Klasse in andere Inhalte einfügen. Frame bietet die gleiche Unterstützung wie NavigationWindow und XBAPs.

Das folgende Beispiel zeigt, wie Sie mithilfe des Frame-Elements ein Page einem Frame deklarativ hinzufügen.

<Page 
  xmlns="http://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 Pack-URI festgelegt, zu dem die Page zunächst navigieren sollte. In der folgenden Abbildung wird ein XBAP mit einem Page gezeigt, das sich zwischen mehreren Seiten bewegt hat.

Ein Frame, der zwischen mehreren Seiten navigiert wurde

Sie müssen Frame nicht ausschließlich innerhalb des Inhalts eines Page verwenden. Es ist auch üblich, ein Frame in den Inhalt eines Window zu integrieren.

Frame verwendet standardmäßig nur sein eigenes Journal, wenn kein anderes Journal vorhanden ist. Wenn ein Frame Teil von Inhalten ist, die entweder in einem NavigationWindow oder einem XBAP gehostet werden, verwendet Frame das Journal, das zum NavigationWindow oder XBAP gehört. Manchmal muss jedoch ein Frame für sein eigenes Journal verantwortlich sein. Ein Grund hierfür ist das Zulassen der Journalnavigation innerhalb der Seiten, die von einer Framegehostet werden. Dies ist in der folgenden Abbildung dargestellt.

Rahmen- und Seitendiagramm

In diesem Fall können Sie Frame so konfigurieren, dass es sein eigenes Journal verwendet, indem Sie die JournalOwnership Eigenschaft von Frame auf OwnsJournal festlegen. Dies wird im folgenden Markup gezeigt.

<Page 
  xmlns="http://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 innerhalb eines Frame, das sein eigenes Journal verwendet, veranschaulicht.

Ein Frame, der ein eigenes Journal verwendet

Beachten Sie, dass die Journaleinträge nicht von Internet Explorer, sondern von der Navigationsbenutzeroberfläche Frameangezeigt werden.

Hinweis

Wenn ein Frame Teil von Inhalten ist, die in einem Windowgehostet werden, Frame verwendet ein eigenes Journal und zeigt folglich eine eigene Navigations-UI an.

Wenn Ihre Benutzeroberfläche ein eigenes Frame-Journal bereitstellen muss, ohne die Navigationsoberfläche anzuzeigen, können Sie die Navigationsoberfläche ausblenden, indem Sie NavigationUIVisibility auf Hidden setzen. Dies wird im folgenden Markup gezeigt.

<Page 
  xmlns="http://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 Inhalten navigieren und anzeigen kann. Dazu verwendet jeder Navigationshost ein eigenes NavigationService und ein eigenes Journal. Die grundlegende Konstruktion eines Navigationshosts ist in der folgenden Abbildung dargestellt.

Navigatordiagramme

Dies ermöglicht NavigationWindow und Frame, im Wesentlichen die gleiche Navigationsunterstützung zu bieten wie ein XBAP, wenn dieser im Browser gehostet wird.

Neben der Verwendung von NavigationService und eines Journals implementieren Navigationshosts dieselben Member, die NavigationService implementiert. Dies ist in der folgenden Abbildung dargestellt.

Ein Journal in einem Frame und einem

Auf diese Weise können Sie die Navigationsunterstützung direkt gegen sie programmieren. Sie können dies in Betracht ziehen, wenn Sie eine benutzerdefinierte Navigations-UI für ein Frame, das in einer Window gehostet wird, bereitstellen müssen. Darüber hinaus implementieren beide Typen zusätzliche, navigationsbezogene Member, einschließlich BackStack (NavigationWindow.BackStack, Frame.BackStack) und ForwardStack (NavigationWindow.ForwardStack, Frame.ForwardStack), mit denen Sie die Journaleinträge im Hintergrundstapel und Vorwärtsstapel entsprechend aufzählen können.

Wie bereits erwähnt, können mehrere Journale innerhalb einer Anwendung vorhanden sein. Die folgende Abbildung zeigt ein Beispiel dafür, wann dies geschehen kann.

Mehrere Journale innerhalb einer Anwendung Dies

In diesem Thema wurden Page und Pack-XBAPs verwendet, um die verschiedenen Navigationsfunktionen von WPF zu veranschaulichen. Ein Page in eine Anwendung kompiliertes Inhaltspaket ist jedoch nicht der einzige Inhaltstyp, zu dem navigiert werden kann, und das Packen von XBAPs ist nicht die einzige Möglichkeit zum Identifizieren von Inhalten.

Wie in diesem Abschnitt gezeigt, können Sie auch zu eigenständigen XAML-Dateien, HTML-Dateien und -Objekten navigieren.

Eine lose XAML-Datei ist eine Datei mit den folgenden Merkmalen:

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

  • Verfügt über eine entsprechende Namespacedeklaration.

  • Hat die Dateinamenerweiterung .xaml.

Betrachten Sie beispielsweise den folgenden Inhalt, der als lose XAML-Datei , Person.xaml, gespeichert ist.

<!-- Person.xaml -->
<TextBlock xmlns="http://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 zum Inhalt. Das wird in der folgenden Abbildung gezeigt.

Anzeige des Inhalts in der Datei

Sie können eine lose XAML-Datei wie folgt anzeigen:

  • Eine Website auf dem lokalen Computer, dem Intranet oder dem Internet.

  • Eine UNC-Dateifreigabe (Universal Naming Convention).

  • Der lokale Datenträger.

Eine lose XAML-Datei kann den Favoriten des Browsers oder der Startseite des Browsers hinzugefügt werden.

Hinweis

Weitere Informationen zum Veröffentlichen und Starten loser XAML-Seiten finden Sie unter Bereitstellen einer WPF-Anwendung.

Eine Einschränkung bei losem XAML besteht darin, dass Sie nur Inhalte hosten können, die sicher in einer teilweisen Vertrauensumgebung ausgeführt werden können. Das Stammelement einer losen XAML-Datei kann beispielsweise Window nicht sein. Weitere Informationen finden Sie unter WPF-Sicherheit mit teilweiser Vertrauenswürdigkeit.

Wie Sie erwarten, können Sie auch zu HTML navigieren. Sie müssen lediglich einen URI bereitstellen, der das HTTP-Schema verwendet. Im folgenden XAML-Code wird beispielsweise ein Frame gezeigt, das zu einer HTML-Seite navigiert.

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

Für die Navigation zu HTML sind spezielle Berechtigungen erforderlich. Man kann beispielsweise nicht von einem XBAP navigieren, das in der Sicherheits-Sandbox der Internetzone mit beschränktem Vertrauen ausgeführt wird. Weitere Informationen finden Sie unter WPF-Sicherheit mit teilweiser Vertrauenswürdigkeit.

Das WebBrowser Steuerelement unterstützt das Hosting von HTML-Dokumenten, die Navigation und die Interoperabilität zwischen Skripten und verwaltetem Code. Ausführliche Informationen zum WebBrowser Steuerelement finden Sie unter WebBrowser.

Wie Frame das Navigieren zu HTML mit WebBrowser spezielle Berechtigungen erfordert. Beispielsweise können Sie aus einer teilweise vertrauenswürdigen Anwendung nur zu HTML navigieren, die sich auf der Ursprungswebsite befindet. Weitere Informationen finden Sie unter WPF-Sicherheit mit teilweiser Vertrauenswürdigkeit.

Wenn Daten als benutzerdefinierte Objekte gespeichert sind, besteht eine Möglichkeit zum Anzeigen dieser Daten darin, einen Page Inhalt zu erstellen, der an diese Objekte gebunden ist (siehe Datenbindungsübersicht). Wenn Sie nicht den Aufwand zum Erstellen einer ganzen Seite benötigen, um die Objekte anzuzeigen, können Sie stattdessen direkt zu ihnen navigieren.

Berücksichtigen Sie die Person Klasse, die im folgenden Code implementiert ist.

using System.Windows.Media;

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; }
        }
    }
}

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

Um dorthin zu navigieren, rufen Sie die NavigationWindow.Navigate Methode auf, wie im folgenden Code veranschaulicht.

<Page 
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://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>
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;

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);
        }
    }
}

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

Die folgende Abbildung zeigt das erwartete Ergebnis.

Eine Seite, die zu einer Klasse navigiert

In dieser Abbildung können Sie sehen, dass nichts Hilfreiches angezeigt wird. Tatsächlich ist der angezeigte Wert der Rückgabewert der ToString Methode für das Person-Objekt . Standardmäßig ist dies der einzige Wert, den WPF zum Darstellen des Objekts verwenden kann. Sie könnten die ToString Methode außer Kraft setzen, um aussagekräftigere Informationen zurückzugeben, obwohl sie immer noch nur ein Zeichenfolgenwert ist. Eine Technik, die Sie verwenden können, um die Darstellungsfunktionen von WPF zu nutzen, besteht darin, eine Datenvorlage zu verwenden. Sie können eine Datenvorlage implementieren, die WPF einem Objekt eines bestimmten Typs zuordnen kann. Der folgende Code zeigt eine Datenvorlage für das Person Objekt.

<Application
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://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="http://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>

Hier wird die Datenvorlage dem Person Typ zugeordnet, indem die x:Type Markuperweiterung im DataType Attribut verwendet wird. Die Datenvorlage bindet TextBlock dann Elemente (siehe TextBlock) an die Eigenschaften der Person Klasse. Die folgende Abbildung zeigt die aktualisierte Darstellung des Person Objekts.

Navigieren zu einer Klasse mit einer Datenvorlage

Ein Vorteil dieser Technik ist die Konsistenz, die Sie erzielen, indem Sie die Datenvorlage wiederverwenden können, um Ihre Objekte überall in Ihrer Anwendung konsistent anzuzeigen.

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

Sicherheit

Die WPF-Navigationsunterstützung ermöglicht die Navigation von XBAPs über das Internet hinweg und ermöglicht Anwendungen das Hosten von Drittanbieterinhalten. Um sowohl Anwendungen als auch Benutzer vor schädlichem Verhalten zu schützen, bietet WPF eine Vielzahl von Sicherheitsfeatures, die in Sicherheit und WPF Partial Trust Security behandelt werden.

Siehe auch