Przegląd Nawigacja
Windows Presentation Foundation (WPF) obsługuje nawigację w stylu przeglądarki, która może być używana w dwóch typach aplikacji: autonomicznych aplikacji i aplikacji przeglądarki XAML (XBAPs). Aby spakować zawartość na potrzeby nawigacji, WPF udostępnia klasę Page . Możesz przechodzić z jednego Page do innego deklaratywnie, używając metody Hyperlink, lub programowo, przy użyciu polecenia NavigationService. WPF używa dziennika do zapamiętowania stron, które zostały nawigowane z i, aby wrócić do nich.
Page, Hyperlink, NavigationServicei dziennik tworzą rdzeń obsługi nawigacji oferowanej przez WPF. To omówienie zawiera szczegółowe omówienie tych funkcji przed omówieniem zaawansowanej obsługi nawigacji, która obejmuje nawigację do luźnych plików języka XAML (Extensible Application Markup Language), plików HTML i obiektów.
Uwaga
W tym temacie termin "przeglądarka" odnosi się tylko do przeglądarek, które mogą hostować aplikacje WPF, które obecnie obejmują programy Microsoft Internet Explorer i Firefox. Jeśli określone funkcje WPF są obsługiwane tylko przez określoną przeglądarkę, wersja przeglądarki jest określana.
Nawigacja w aplikacjach WPF
Ten temat zawiera omówienie kluczowych funkcji nawigacji w WPF. Te możliwości są dostępne zarówno dla aplikacji autonomicznych, jak i XBAPs, chociaż ten temat przedstawia je w kontekście XBAP.
Uwaga
W tym temacie nie omówiono sposobu kompilowania i wdrażania XBAPs. Aby uzyskać więcej informacji na temat XBAPs, zobacz WPF XAML Browser Applications Overview (Omówienie aplikacji przeglądarki WPF XAML).
W tej sekcji opisano i przedstawiono następujące aspekty nawigacji:
Implementowanie strony
W programie WPF można przejść do kilku typów zawartości, które obejmują obiekty .NET Framework, obiekty niestandardowe, wartości wyliczenia, kontrolki użytkownika, pliki XAML i pliki HTML. Jednak dowiesz się, że najczęściej używanym i wygodnym sposobem spakowania zawartości jest użycie polecenia Page. Ponadto implementuje funkcje specyficzne dla nawigacji, Page aby poprawić wygląd i uprościć programowanie.
Za pomocą Pagemetody można deklaratywne zaimplementować stronę zawartości XAML z możliwością nawigacji przy użyciu znaczników, takich jak poniżej.
<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" />
Element Page implementowany w adiustacji XAML ma Page jako element główny i wymaga deklaracji przestrzeni nazw XML WPF. Element Page zawiera zawartość, do której chcesz przejść i wyświetlić. Dodasz zawartość, ustawiając Page.Content element właściwości, jak pokazano w poniższym znaczniku.
<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<Page.Content>
<!-- Page Content -->
Hello, Page!
</Page.Content>
</Page>
Page.Content może zawierać tylko jeden element podrzędny; w poprzednim przykładzie zawartość jest pojedynczym ciągiem"Hello, Page!" W praktyce zwykle używasz kontrolki układu jako elementu podrzędnego (zobacz Układ), aby zawierać i tworzyć zawartość.
Elementy Page podrzędne elementu są uważane za zawartość elementu Page i w związku z tym nie trzeba używać jawnej Page.Content deklaracji. Poniższy znacznik jest deklaratywnym odpowiednikiem poprzedniej próbki.
<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<!-- Page Content -->
Hello, Page!
</Page>
W takim przypadku Page.Content jest automatycznie ustawiana z elementami podrzędnymi Page elementu. Aby uzyskać więcej informacji, zobacz Model zawartości WPF.
Znaczniki Page są przydatne do wyświetlania zawartości. Jednak może Page również wyświetlać kontrolki, które umożliwiają użytkownikom interakcję ze stroną i mogą reagować na interakcję użytkownika, obsługując zdarzenia i wywołując logikę aplikacji. Interakcyjny Page jest implementowany przy użyciu kombinacji znaczników i kodu w tle, jak pokazano w poniższym przykładzie.
<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
Aby umożliwić współdziałanie pliku znaczników i pliku z kodem, wymagana jest następująca konfiguracja:
W znacznikach
Pageelement musi zawieraćx:Classatrybut. Gdy aplikacja zostanie skompilowana, istnieniex:Classw pliku znaczników powoduje, że aparat kompilacji firmy Microsoft (MSBuild) utworzy klasępartial, która pochodzi z Page i ma nazwę określoną przezx:Classatrybut . Wymaga to dodania deklaracji przestrzeni nazw XML dla schematu XAML (xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"). Wygenerowanapartialklasa implementujeInitializeComponentmetodę , która jest wywoływana w celu zarejestrowania zdarzeń i ustawienia właściwości implementowanych w adiustacji.W kodzie klasa musi być klasą
partialo tej samej nazwie, która jest określona przezx:Classatrybut w znacznikach, i musi pochodzić z Pageklasy . Umożliwia to skojarzenie pliku za pomocą kodu z klasąpartialwygenerowaną dla pliku znaczników podczas kompilowania aplikacji (zobacz Tworzenie aplikacji WPF).W kodzie Page klasa musi zaimplementować konstruktor, który wywołuje metodę
InitializeComponent.InitializeComponentjest implementowany przez wygenerowanąpartialklasę pliku znaczników w celu rejestrowania zdarzeń i ustawiania właściwości zdefiniowanych w adiustacji.
Uwaga
Po dodaniu nowego Page do projektu przy użyciu Visual Studio Page implementacja jest implementowana przy użyciu znaczników i kodu za pomocą kodu, a także zawiera niezbędną konfigurację do utworzenia skojarzenia między znacznikami i plikami kodu zgodnie z opisem w tym miejscu.
Po utworzeniu elementu Pagemożesz przejść do niego. Aby określić pierwszy Page , do którego przechodzi aplikacja, należy skonfigurować polecenie uruchamiania Page.
Konfigurowanie strony początkowej
XBAPs wymagają, aby w przeglądarce była hostowana pewna ilość infrastruktury aplikacji. W programie WPF Application klasa jest częścią definicji aplikacji, która ustanawia wymaganą infrastrukturę aplikacji (zobacz Omówienie zarządzania aplikacjami).
Definicja aplikacji jest zwykle implementowana przy użyciu znaczników i kodu za pomocą pliku znaczników skonfigurowanego jako element MSBuildApplicationDefinition. Poniżej przedstawiono definicję aplikacji dla 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
XBAP może użyć jego definicji aplikacji, aby określić start Page, który jest Page automatycznie ładowany po uruchomieniu XBAP. W tym celu należy ustawić StartupUri właściwość z identyfikatorem URI (Uniform Resource Identifier) dla żądanego Pageelementu .
Uwaga
W większości przypadków element Page jest kompilowany do lub wdrażany przy użyciu aplikacji. W takich przypadkach identyfikator URI, który identyfikuje element Page , jest identyfikatorem URI pakietu, który jest identyfikatorem URI zgodnym ze schematem pakietów . Identyfikatory URI pakietów zostały omówione bardziej szczegółowo w temacie Identyfikatory URI pakietów w WPF. Możesz również przejść do zawartości przy użyciu schematu http, który został omówiony poniżej.
Możesz ustawić StartupUri deklaratywnie w znacznikach, jak pokazano w poniższym przykładzie.
<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" />
W tym przykładzie StartupUri atrybut jest ustawiany przy użyciu względnego identyfikatora URI pakietu, który identyfikuje plik HomePage.xaml. Po uruchomieniu XBAP plik HomePage.xaml jest automatycznie nawigowany do i wyświetlany. Jest to pokazane na poniższej ilustracji, która pokazuje XBAP, który został uruchomiony z serwera sieci Web.

Uwaga
Aby uzyskać więcej informacji na temat programowania i wdrażania XBAPs, zobacz WPF XAML Browser Applications Overview and Deploying a WPF Application (Omówienie aplikacji przeglądarki WPF i wdrażanie aplikacji WPF).
Konfigurowanie tytułu, szerokości i wysokości okna hosta
Jedną z rzeczy, które można zauważyć na poprzedniej ilustracji, jest to, że tytuł przeglądarki i panelu kart to identyfikator URI XBAP. Oprócz długiego, tytuł nie jest ani atrakcyjny, ani informacyjny. Z tego powodu Page oferuje sposób zmiany tytułu przez ustawienie WindowTitle właściwości. Ponadto można skonfigurować szerokość i wysokość okna przeglądarki, ustawiając WindowWidth odpowiednio wartości i WindowHeight.
WindowTitle, WindowWidthi WindowHeight można ustawić deklaratywnie w znacznikach, jak pokazano w poniższym przykładzie.
<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>
Wynik pokazano na poniższej ilustracji.

Nawigacja hiperlinków
Typowy kod XBAP składa się z kilku stron. Najprostszym sposobem na przejście z jednej strony do innej jest użycie elementu Hyperlink. Możesz deklaratywnie dodać element Hyperlink do elementu Page przy użyciu Hyperlink elementu, który jest wyświetlany w poniższym znaczniku.
<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>
Element Hyperlink wymaga następujących elementów:
Identyfikator URI pakietu do Page przejścia do, określony przez
NavigateUriatrybut .Zawartość, którą użytkownik może kliknąć, aby zainicjować nawigację, taką jak tekst i obrazy (aby uzyskać zawartość, którą
Hyperlinkmoże zawierać element, zobacz Hyperlink).
Na poniższej ilustracji przedstawiono XBAP z elementem Page o wartości Hyperlink.

Jak można się spodziewać, kliknięcie Hyperlink powoduje przejście XBAP do Page elementu identyfikowane przez NavigateUri atrybut . Ponadto XBAP dodaje wpis dla poprzedniej Page listy Ostatnie strony w programie Internet Explorer. Jest to pokazane na poniższej ilustracji.

Ponadto obsługa nawigacji między elementami PageHyperlink obsługuje również nawigację po fragmentach.
Nawigacja po fragmentach
Nawigacja po fragmentach to nawigacja do fragmentu zawartości w bieżącym Page lub innym elemencie Page. W WPF fragment zawartości jest zawartością zawartą przez nazwany element. Nazwany element jest elementem, który ma swój Name zestaw atrybutów. Poniższy znacznik przedstawia nazwany TextBlock element, który zawiera fragment zawartości.
<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>
Hyperlink Aby przejść do fragmentu zawartości, NavigateUri atrybut musi zawierać następujące elementy:
Identyfikator URI obiektu Page z fragmentem zawartości, do których ma przejść.
Znak "#".
Nazwa elementu na Page obiekcie, który zawiera fragment zawartości.
Identyfikator URI fragmentu ma następujący format.
Identyfikator PageURI#Elementname
Poniżej przedstawiono przykład obiektu Hyperlink skonfigurowanego do przechodzenia do fragmentu zawartości.
<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>
Uwaga
W tej sekcji opisano domyślną implementację nawigacji fragmentu w WPF. Platforma WPF umożliwia również zaimplementowanie własnego schematu nawigacji fragmentów, który po części wymaga obsługi NavigationService.FragmentNavigation zdarzenia.
Ważne
Możesz przechodzić do fragmentów na luźnych stronach XAML (pliki XAML tylko znaczników z Page elementem głównym) tylko wtedy, gdy strony można przeglądać za pośrednictwem protokołu HTTP.
Jednak luźna strona XAML może przechodzić do własnych fragmentów.
Usługa nawigacji
Chociaż Hyperlink umożliwia użytkownikowi zainicjowanie nawigacji do określonego Pageelementu , praca lokalizowania i pobierania strony jest wykonywana przez klasę NavigationService . NavigationService Zasadniczo zapewnia możliwość przetwarzania żądania nawigacji w imieniu kodu klienta, takiego jak Hyperlink. NavigationService Ponadto implementuje obsługę wyższego poziomu na potrzeby śledzenia i wpływania na żądanie nawigacji.
Po kliknięciu elementu Hyperlink WPF wywołuje metodę NavigationService.Navigate w celu zlokalizowania i pobrania identyfikatora Page URI określonego pakietu. Pobrany obiekt jest konwertowany Page na drzewo obiektów, których obiekt główny jest wystąpieniem pobranego Pageobiektu . Odwołanie do obiektu głównego Page jest przechowywane we NavigationService.Content właściwości . Identyfikator URI pakietu dla zawartości, do której został przekierowany, jest przechowywany we NavigationService.Source właściwości , podczas gdy NavigationService.CurrentSource identyfikator URI pakietu jest przechowywany dla ostatniej strony, do której została wyświetlona.
Uwaga
Aplikacja WPF może mieć więcej niż jedną aktywną NavigationService. Aby uzyskać więcej informacji, zobacz Nawigacja hosty w dalszej części tego tematu.
Nawigacja programowa za pomocą usługi nawigacji
Nie musisz wiedzieć, NavigationService czy nawigacja jest implementowana deklaratywnie w adiustacji przy użyciu elementu Hyperlink, ponieważ Hyperlink używa elementu NavigationService w Twoim imieniu. Oznacza to, że tak długo, jak bezpośredni lub pośredni element nadrzędny elementu Hyperlink jest hostem nawigacji (zobacz Hosty nawigacji), Hyperlink będzie mógł znaleźć usługę nawigacji hosta nawigacji i użyć jej do przetworzenia żądania nawigacji.
Istnieją jednak sytuacje, w których należy użyć NavigationService bezpośrednio, w tym następujące kwestie:
Jeśli musisz utworzyć wystąpienie Page przy użyciu konstruktora bez parametrów.
Gdy musisz ustawić właściwości na obiekcie Page przed przejściem do niego.
Po przejściu Page do elementu , do którego należy przejść, można określić tylko w czasie wykonywania.
W takich sytuacjach należy napisać kod, aby programowo zainicjować nawigację przez wywołanie Navigate metody NavigationService obiektu. Wymaga to uzyskania odwołania do .NavigationService
Uzyskiwanie odwołania do elementu NavigationService
Ze względów opisanych w sekcji Hosty nawigacji aplikacja WPF może mieć więcej niż jeden NavigationServiceelement . Oznacza to, że kod wymaga sposobu znalezienia NavigationServiceelementu , który zazwyczaj NavigationService przechodzi do bieżącego Pageelementu . Odwołanie do obiektu NavigationService można uzyskać, wywołując metodę staticNavigationService.GetNavigationService . Aby uzyskać element NavigationService przechodzący do określonego Pageelementu , należy przekazać odwołanie do Page metody jako argument GetNavigationService metody . Poniższy kod pokazuje, jak pobrać element NavigationService dla bieżącego Pageelementu .
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)
Jako skrót do znajdowania NavigationService elementu dla elementu Page, Page implementuje NavigationService właściwość . Jest to pokazane w poniższym przykładzie.
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
Uwaga
Element Page może uzyskać odwołanie tylko do jego NavigationService , gdy Page zgłasza Loaded zdarzenie.
Programowa nawigacja do obiektu strony
W poniższym przykładzie pokazano, jak za pomocą polecenia NavigationService programowo przejść do elementu Page. Nawigacja programowa jest wymagana, ponieważ Page obiekt, do którego jest nawigowany, można utworzyć wystąpienie tylko przy użyciu jednego konstruktora bez parametrów. Element Page z konstruktorem bez parametrów jest wyświetlany w poniższych znacznikach i kodzie.
<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
Obiekt Page , który przechodzi do metody Page za pomocą konstruktora bez parametrów, jest wyświetlany w poniższych znacznikach i kodzie.
<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
Po kliknięciu Hyperlink tego Page elementu nawigacja jest inicjowana przez utworzenie wystąpienia Page elementu , aby przejść do przy użyciu konstruktora bez parametrów i wywołania NavigationService.Navigate metody . Navigate akceptuje odwołanie do obiektu, do którego NavigationService przejdzie obiekt, a nie do identyfikatora URI pakietu.
Programowa nawigacja przy użyciu identyfikatora URI pakietu
Jeśli musisz skonstruować identyfikator URI pakietu programowo (jeśli można określić tylko identyfikator URI pakietu w czasie wykonywania), możesz użyć NavigationService.Navigate metody . Jest to pokazane w poniższym przykładzie.
<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
Odświeżanie bieżącej strony
Element Page nie jest pobierany, jeśli ma ten sam identyfikator URI pakietu co identyfikator URI pakietu przechowywany we NavigationService.Source właściwości . Aby wymusić ponowne pobranie bieżącej strony w programie WPF, możesz wywołać metodę NavigationService.Refresh , jak pokazano w poniższym przykładzie.
<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
Okres istnienia nawigacji
Istnieje wiele sposobów inicjowania nawigacji, jak pokazano. Gdy nawigacja jest inicjowana, a nawigacja jest w toku, możesz śledzić nawigację i wpływać na nie przy użyciu następujących zdarzeń implementowanych przez NavigationServiceprogram :
Navigating. Występuje, gdy jest wymagane nowe nawigowanie. Może służyć do anulowania nawigacji.
NavigationProgress. Występuje okresowo podczas pobierania, aby zapewnić informacje o postępie nawigacji.
Navigated. Występuje, gdy strona została zlokalizowana i pobrana.
NavigationStopped. Występuje, gdy nawigacja jest zatrzymana (przez wywołanie metody StopLoading), lub gdy jest żądana nowa nawigacja, gdy bieżąca nawigacja jest w toku.
NavigationFailed. Występuje, gdy podczas przechodzenia do żądanej zawartości jest zgłaszany błąd.
LoadCompleted. Występuje po załadowaniu i przeanalizowaniu zawartości, do którego nastąpiło przejście, i rozpoczęciu renderowania.
FragmentNavigation. Występuje po rozpoczęciu nawigacji do fragmentu zawartości:
Natychmiast, jeśli żądany fragment znajduje się w bieżącej zawartości.
Po załadowaniu zawartości źródłowej, jeśli żądany fragment znajduje się w innej zawartości.
Zdarzenia nawigacji są wywoływane w kolejności ilustrowanej przez poniższą ilustrację.

Ogólnie rzecz biorąc, nie jest zaniepokojony Page tymi zdarzeniami. Istnieje większe prawdopodobieństwo, że aplikacja jest z nimi zaniepokojona i z tego powodu te zdarzenia są również zgłaszane przez klasę Application :
Za każdym razem, gdy NavigationService zgłasza zdarzenie, Application klasa zgłasza odpowiednie zdarzenie. Frame i NavigationWindow oferują te same zdarzenia do wykrywania nawigacji w odpowiednich zakresach.
W niektórych przypadkach Page mogą być zainteresowane tymi wydarzeniami. Może na przykład obsługiwać NavigationService.Navigating zdarzenie, aby określić, Page czy anulować nawigację niezależnie od siebie. Jest to pokazane w poniższym przykładzie.
<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
W przypadku zarejestrowania programu obsługi przy użyciu zdarzenia nawigacji z Pageprogramu , jak w poprzednim przykładzie, należy również wyrejestrować program obsługi zdarzeń. Jeśli nie, mogą wystąpić skutki uboczne w odniesieniu do sposobu, w jaki nawigacja WPF zapamiętuje Page nawigację przy użyciu dziennika.
Zapamiętując nawigację za pomocą dziennika
Platforma WPF używa dwóch stosów do zapamiętania stron, z których korzystasz: stosu wstecznego i stosu do przodu. Po przejściu z bieżącej Page do nowej Page lub do przodu do istniejącej Page, bieżący Page jest dodawany do stosu wstecznego. Po przejściu z bieżącego Page z powrotem do poprzedniego Pageelementu bieżący Page element jest dodawany do stosu do przodu. Stos wsteczny, stos do przodu i funkcje do zarządzania nimi są określane zbiorczo jako dziennik. Każdy element w stosie wstecznym i stosie JournalEntry do przodu jest wystąpieniem klasy i jest określany jako wpis dziennika.
Nawigowanie po dzienniku z programu Internet Explorer
Koncepcyjnie dziennik działa w taki sam sposób, jak przyciski Wstecz i Prześlij dalej w programie Internet Explorer. Są one pokazane na poniższej ilustracji.

W przypadku XBAPs hostowanych przez program Internet Explorer WPF integruje dziennik z interfejsem użytkownika nawigacji programu Internet Explorer. Dzięki temu użytkownicy mogą nawigować po stronach w XBAP za pomocą przycisków Wstecz, Prześlij dalej i Ostatnie strony w programie Internet Explorer.
Ważne
W programie Internet Explorer, gdy użytkownik przechodzi z dala od i z powrotem do XBAP, tylko wpisy dziennika dla stron, które nie były przechowywane przy życiu, są przechowywane w dzienniku. Aby zapoznać się z dyskusją na temat utrzymania aktywności stron, zobacz Okres istnienia strony i Dziennik w dalszej części tego tematu.
Domyślnie tekst każdego Page , który jest wyświetlany na liście Ostatnie strony programu Internet Explorer, jest identyfikatorem URI dla elementu Page. W wielu przypadkach nie jest to szczególnie istotne dla użytkownika. Na szczęście możesz zmienić tekst przy użyciu jednej z następujących opcji:
Dołączona
JournalEntry.Namewartość atrybutu.Wartość atrybutu
Page.Title.Wartość
Page.WindowTitleatrybutu i identyfikator URI dla bieżącego Pageelementu .Identyfikator URI dla bieżącego Pageelementu . (Domyślnie)
Kolejność wyświetlania opcji jest zgodna z kolejnością pierwszeństwa podczas znajdowania tekstu. Jeśli na przykład JournalEntry.Name jest ustawiona, pozostałe wartości są ignorowane.
W poniższym przykładzie użyto atrybutu Page.Title , aby zmienić tekst wyświetlany dla wpisu dziennika.
<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
Nawigowanie po dzienniku przy użyciu WPF
Chociaż użytkownik może nawigować po dzienniku przy użyciu stron wstecz, do przodu i ostatnich w programie Internet Explorer, możesz również nawigować po dzienniku przy użyciu zarówno deklaratywnych, jak i programowych mechanizmów dostarczanych przez WPF. Jednym z powodów jest zapewnienie niestandardowych interfejsów użytkownika nawigacji na stronach.
Obsługę nawigacji dziennika można deklaratywnie dodać przy użyciu poleceń nawigacji udostępnianych przez NavigationCommandsprogram . W poniższym przykładzie pokazano, jak używać BrowseBack polecenia nawigacji.
<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>
Możesz programowo nawigować po dzienniku przy użyciu jednego z następujących elementów członkowskich NavigationService klasy:
Dziennik można również manipulować programowo, zgodnie z opisem w sekcji Zachowywanie stanu zawartości z historią nawigacji w dalszej części tego tematu.
Okres istnienia strony i dziennik
Rozważmy XBAP z kilkoma stronami zawierającymi bogatą zawartość, w tym grafikę, animacje i multimedia. Zużycie pamięci dla stron takich jak te może być dość duże, szczególnie jeśli są używane nośniki wideo i audio. Biorąc pod uwagę, że dziennik "zapamiętuje" strony, do których przechodzino, taki XBAP może szybko zużywać dużą i zauważalną ilość pamięci.
Z tego powodu domyślnym zachowaniem dziennika jest przechowywanie Page metadanych w każdym wpisie dziennika, a nie odwołanie do Page obiektu. Po przejściu do wpisu dziennika jego Page metadane są używane do utworzenia nowego wystąpienia określonego Pageelementu . W związku z tym każdy Page , który jest nawigowany, ma okres istnienia ilustrowany na poniższej ilustracji.

Chociaż użycie domyślnego zachowania dziennika może zaoszczędzić na użyciu pamięci, wydajność renderowania na stronie może zostać zmniejszona; ponowne potwierdzenie Page może być czasochłonne, szczególnie jeśli ma dużo zawartości. Jeśli musisz zachować Page wystąpienie w dzienniku, możesz rysować na dwóch technikach, aby to zrobić. Najpierw można programowo przejść do Page obiektu, wywołując metodę NavigationService.Navigate .
Po drugie, można określić, że WPF zachować wystąpienie Page obiektu w dzienniku, ustawiając KeepAlive właściwość na true (wartość domyślna to false). Jak pokazano w poniższym przykładzie, można ustawić KeepAlive deklaratywnie w adiustacji.
<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>
Okres życia, Page który jest utrzymywany przy życiu, jest subtelnie inny niż ten, który nie jest. Po raz pierwszy, Page do którego jest utrzymywana żywa, jest tworzone wystąpienie, podobnie jak to Page , które nie jest utrzymywane przy życiu. Jednak ze względu na to, że wystąpienie obiektu Page jest przechowywane w dzienniku, nigdy nie jest tworzone ponownie tak długo, jak pozostaje w dzienniku. W związku z tym, jeśli element Page ma logikę inicjowania, która musi być wywoływana za każdym razem Page , gdy jest nawigowany, należy przenieść go z konstruktora do procedury obsługi zdarzenia Loaded . Jak pokazano na poniższej ilustracji, Loaded zdarzenia i Unloaded są nadal wywoływane za każdym razem, gdy Page następuje odpowiednio przejście do i z.

Jeśli element Page nie jest utrzymywany przy życiu, nie należy wykonywać żadnej z następujących czynności:
Zapisz odwołanie do niego lub dowolną jego część.
Rejestrowanie procedur obsługi zdarzeń za pomocą zdarzeń, które nie są przez nią implementowane.
Wykonanie jednej z tych czynności spowoduje utworzenie odwołań, które wymuszają Page zachowanie elementu w pamięci, nawet po usunięciu go z dziennika.
Ogólnie rzecz biorąc, wolisz domyślne Page zachowanie, które nie utrzymuje Page aktywności. Jednak ma to wpływ na stan, które zostały omówione w następnej sekcji.
Zachowywanie stanu zawartości z historią nawigacji
Jeśli obiekt Page nie jest aktywny i ma kontrolki, które zbierają dane od użytkownika, co się stanie z danymi, jeśli użytkownik przejdzie z dala od i z powrotem do obiektu Page? Z perspektywy środowiska użytkownika użytkownik powinien oczekiwać, że dane wprowadzone wcześniej. Niestety, ponieważ nowe wystąpienie obiektu Page jest tworzone przy użyciu każdej nawigacji, kontrolki, które zbierały dane, są ponownie uzasadnione i dane zostaną utracone.
Na szczęście dziennik zapewnia obsługę zapamiętowania danych między Page nawigacjami, w tym danych sterujących. W szczególności wpis dziennika dla każdego Page działa jako kontener tymczasowy dla skojarzonego Page stanu. W poniższych krokach opisano sposób użycia tej obsługi po przejściu z elementu Page :
Wpis dla bieżącego Page jest dodawany do dziennika.
Stan Page obiektu jest przechowywany z wpisem dziennika dla tej strony, który jest dodawany do stosu wstecznego.
Page Nowy jest nawigowany do.
Po powrocie do strony Page , korzystając z dziennika, należy wykonać następujące kroki:
Wystąpienie Page elementu (najwyższego wpisu dziennika na stosie wstecznym).
Jest Page odświeżany ze stanem, który był przechowywany z wpisem dziennika dla .Page
Element Page jest wracany do.
WPF automatycznie używa tej obsługi, gdy następujące kontrolki są używane w elemecie Page:
Jeśli te Page kontrolki używają tych kontrolek, wprowadzone do nich dane są zapamiętywane w Page nawigacji, jak pokazano na poniższej ilustracji przy użyciu koloru ListBoxulubionego.

Jeśli obiekt Page ma kontrolki inne niż te na powyższej liście lub gdy stan jest przechowywany w obiektach niestandardowych, należy napisać kod, aby spowodować zapamiętanie stanu dziennika między Page nawigacjami.
Jeśli musisz pamiętać małe fragmenty stanu między Page nawigacjami, możesz użyć właściwości zależności (zobacz DependencyProperty) skonfigurowanych za pomocą flagi FrameworkPropertyMetadata.Journal metadanych.
Jeśli stan, który Page należy zapamiętać w ramach nawigacji, składa się z wielu fragmentów danych, może być mniej intensywnie obciążający kod, aby hermetyzować stan w jednej klasie i zaimplementować IProvideCustomContentState interfejs.
Jeśli musisz nawigować po różnych stanach pojedynczego Pageelementu , bez przechodzenia od Page samego siebie, możesz użyć metod IProvideCustomContentState i NavigationService.AddBackEntry.
Pliki cookie
Innym sposobem, w jaki aplikacje WPF mogą przechowywać dane, są pliki cookie, które są tworzone, aktualizowane i usuwane przy użyciu SetCookie metod i GetCookie . Pliki cookie, które można utworzyć w WPF są tymi samymi plikami cookie, których używają inne typy aplikacji internetowych; pliki cookie to dowolne elementy danych, które są przechowywane przez aplikację na komputerze klienckim podczas sesji aplikacji lub między sesjami aplikacji. Dane plików cookie zwykle mają postać pary nazwa/wartość w następującym formacie.
Nazwa=Wartość
Po przekazaniu danych do SetCookieobiektu wraz z Uri lokalizacją, dla której ma zostać ustawiony plik cookie, plik cookie jest tworzony w pamięci i jest dostępny tylko przez czas trwania bieżącej sesji aplikacji. Ten typ pliku cookie jest określany jako plik cookie sesji.
Aby przechowywać plik cookie między sesjami aplikacji, należy dodać datę wygaśnięcia do pliku cookie, używając następującego formatu.
NAZWA=WARTOŚĆ; expires=DAY, DD-MMM-YYYY HH:MM:SS GMT
Plik cookie z datą wygaśnięcia jest przechowywany w folderze tymczasowych plików internetowych bieżącej instalacji Windows do momentu wygaśnięcia pliku cookie. Taki plik cookie jest znany jako trwały plik cookie , ponieważ utrzymuje się on między sesjami aplikacji.
Pobierasz zarówno pliki cookie sesji, jak i trwałe, wywołując metodę GetCookie , przekazując Uri lokalizację, w której plik cookie został ustawiony za SetCookie pomocą metody .
Poniżej przedstawiono niektóre sposoby obsługi plików cookie w WPF:
Aplikacje autonomiczne WPF i XBAPs mogą tworzyć pliki cookie i zarządzać nimi.
Dostęp do plików cookie tworzonych przez XBAP można uzyskać z przeglądarki.
XBAPs z tej samej domeny może tworzyć i udostępniać pliki cookie.
Pliki XBAPs i strony HTML z tej samej domeny mogą tworzyć i udostępniać pliki cookie.
Pliki cookie są wysyłane, gdy XBAPs i luźne strony XAML wysyłają żądania internetowe.
Zarówno XBAPs najwyższego poziomu, jak i XBAPs hostowane w elementach IFRAMES mogą uzyskiwać dostęp do plików cookie.
Obsługa plików cookie w WPF jest taka sama dla wszystkich obsługiwanych przeglądarek.
W programie Internet Explorer zasady P3P dotyczące plików cookie są honorowane przez WPF, szczególnie w odniesieniu do firm trzecich i XBAPs innych firm.
Nawigacja ze strukturą
Jeśli musisz przekazać dane z jednego Page do drugiego, możesz przekazać dane jako argumenty do konstruktora bez parametrów obiektu Page. Należy pamiętać, że jeśli używasz tej techniki, musisz zachować Page przy życiu; jeśli nie, przy następnym przejściu Pagedo , WPF ponownie za Page pomocą konstruktora bez parametrów.
Alternatywnie Page możesz zaimplementować właściwości ustawione przy użyciu danych, które należy przekazać. Sytuacja staje się jednak trudna, gdy Page konieczne jest przekazanie danych z powrotem do Page elementu, który do niego przejdzie. Problem polega na tym, że nawigacja nie obsługuje natywnie mechanizmów zagwarantowania, że Page element zostanie zwrócony po przejściu z. Zasadniczo nawigacja nie obsługuje semantyki wywołań/zwrotów. Aby rozwiązać ten problem, WPF udostępnia klasę PageFunction<T> , której można użyć, aby upewnić się, że Page element jest zwracany w przewidywalny i ustrukturyzowany sposób. Aby uzyskać więcej informacji, zobacz Omówienie nawigacji strukturalnej.
Klasa NavigationWindow
W tym momencie przedstawiono gamę usług nawigacji, których najprawdopodobniej będziesz używać do tworzenia aplikacji z zawartością nawigalną. Te usługi zostały omówione w kontekście XBAPs, chociaż nie są one ograniczone do XBAPs. Nowoczesne systemy operacyjne i aplikacje Windows korzystają ze środowiska przeglądarki nowoczesnych użytkowników w celu włączenia nawigacji w stylu przeglądarki do aplikacji autonomicznych. Typowe przykłady obejmują:
Wyraz Thesaurus: Nawigacja po wyborach wyrazów.
Eksplorator plików: nawigowanie po plikach i folderach.
Kreatorzy: podzielenie złożonego zadania na wiele stron, między którymi można przechodzić. Przykładem jest Kreator Windows Components, który obsługuje dodawanie i usuwanie funkcji Windows.
Aby uwzględnić nawigację w stylu przeglądarki w aplikacjach autonomicznych, możesz użyć NavigationWindow klasy . NavigationWindow element pochodzi z Window i rozszerza go o tę samą obsługę nawigacji zapewnianej przez XBAPs. Możesz użyć NavigationWindow jako głównego okna aplikacji autonomicznej lub jako okna pomocniczego, takiego jak okno dialogowe.
Aby zaimplementować klasę NavigationWindow, podobnie jak w przypadku większości klas najwyższego poziomu w WPF (Window, Pageitd.), należy użyć kombinacji znaczników i kodu w tle. Jest to pokazane w poniższym przykładzie.
<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
Ten kod tworzy obiekt NavigationWindow , który automatycznie przechodzi do Page pliku (HomePage.xaml), gdy NavigationWindow obiekt jest otwarty. NavigationWindow Jeśli jest to główne okno aplikacji, możesz użyć atrybutu StartupUri , aby go uruchomić. Jest to pokazane w poniższym znaczniku.
<Application
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
StartupUri="MainWindow.xaml" />
Na poniższej ilustracji przedstawiono NavigationWindow okno główne aplikacji autonomicznej.

Na rysunku widać, że element NavigationWindow ma tytuł, mimo że nie został ustawiony w NavigationWindow kodzie implementacji z poprzedniego przykładu. Zamiast tego tytuł jest ustawiany przy użyciu WindowTitle właściwości , która jest wyświetlana w poniższym kodzie.
<Page
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
Title="Home Page"
WindowTitle="NavigationWindow">
</Page>
WindowWidth Ustawienie właściwości i WindowHeight wpływa również na NavigationWindowelement .
Zwykle implementujesz własne NavigationWindow , gdy trzeba dostosować jego zachowanie lub wygląd. Jeśli nie, możesz użyć skrótu. Jeśli określisz identyfikator URI Page pakietu jako StartupUri w aplikacji autonomicznej, Application program automatycznie utworzy obiekt NavigationWindow do hostowania obiektu Page. W poniższych znacznikach pokazano, jak to włączyć.
<Application
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
StartupUri="HomePage.xaml" />
Jeśli chcesz, aby okno aplikacji pomocniczej, takie jak okno dialogowe było elementem NavigationWindow, możesz użyć kodu w poniższym przykładzie, aby go otworzyć.
// 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()
Na poniższej ilustracji przedstawiono rezultat.

Jak widać, wyświetla przyciski Wstecz i Prześlij dalej w stylu programu Internet Explorer, NavigationWindow które umożliwiają użytkownikom nawigowanie po dzienniku. Te przyciski zapewniają takie samo środowisko użytkownika, jak pokazano na poniższej ilustracji.

Jeśli strony zapewniają własną obsługę nawigacji w dzienniku i interfejs użytkownika, możesz ukryć przyciski Wstecz i Prześlij dalej , NavigationWindow ustawiając wartość ShowsNavigationUI właściwości na false.
Alternatywnie można użyć obsługi dostosowywania w WPF, aby zastąpić interfejs użytkownika NavigationWindow samego siebie.
Klasa ramki
Zarówno przeglądarka, jak i NavigationWindow okna hostujące zawartość z możliwością nawigacji. W niektórych przypadkach aplikacje mają zawartość, która nie musi być hostowana przez całe okno. Zamiast tego taka zawartość jest hostowana wewnątrz innego elementu. Zawartość z możliwością nawigacji można wstawić do innej zawartości przy użyciu Frame klasy . Frame zapewnia taką samą obsługę jak NavigationWindow i XBAPs.
W poniższym przykładzie pokazano, jak dodać element Frame do deklaratywnego FramePage przy użyciu elementu .
<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>
Ten znacznik ustawia Source atrybut Frame elementu za pomocą identyfikatora URI pakietu dla Page elementu, do którego Frame powinien początkowo przejść. Na poniższej ilustracji przedstawiono element XBAP z elementem PageFrame , który przechodzi między kilkoma stronami.

Nie trzeba używać Frame tylko wewnątrz zawartości obiektu Page. Często hostuje się również wewnątrz Frame zawartości obiektu Window.
Domyślnie Frame używa tylko własnego dziennika w przypadku braku innego dziennika. Jeśli element Frame jest częścią zawartości hostowanej wewnątrz NavigationWindow lub XBAP, Frame używa dziennika należącego NavigationWindow do lub XBAP. Czasami jednak Frame może być konieczne, aby być odpowiedzialnym za własny dziennik. Jednym z powodów jest zezwolenie na nawigację w dziennikach na stronach hostowanych przez obiekt Frame. Jest to zilustrowane na poniższym rysunku.

W takim przypadku można skonfigurować obiekt Frame tak, aby używał własnego dziennika, ustawiając JournalOwnership właściwość właściwości na FrameOwnsJournal. Jest to pokazane w poniższym znaczniku.
<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>
Na poniższej ilustracji przedstawiono efekt nawigowania w obrębie obiektu Frame , który używa własnego dziennika.

Zwróć uwagę, że wpisy dziennika są wyświetlane przez interfejs użytkownika nawigacji w programie Frame, a nie w programie Internet Explorer.
Uwaga
Jeśli element Frame jest częścią zawartości hostowanej w obiekcie Window, Frame używa własnego dziennika i w związku z tym wyświetla własny interfejs użytkownika nawigacji.
Jeśli środowisko użytkownika wymaga Frame podania własnego dziennika bez wyświetlania interfejsu użytkownika nawigacji, możesz ukryć interfejs użytkownika nawigacji, ustawiając wartość NavigationUIVisibilityHidden. Jest to pokazane w poniższym znaczniku.
<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>
Hosty nawigacji
Frame i NavigationWindow są klasami, które są nazywane hostami nawigacji. Host nawigacji to klasa, która może przechodzić do zawartości i wyświetlać jej zawartość. W tym celu każdy host nawigacji używa własnego NavigationService dziennika i . Podstawowa konstrukcja hosta nawigacji jest pokazana na poniższej ilustracji.

Zasadniczo umożliwia NavigationWindow to i Frame zapewnia tę samą obsługę nawigacji zapewnianą przez XBAP w przypadku hostowania w przeglądarce.
Oprócz używania NavigationService i dziennika hosty nawigacji implementują te same elementy członkowskie, które NavigationService implementują. Jest to zilustrowane na poniższym rysunku.

Dzięki temu można programować obsługę nawigacji bezpośrednio przeciwko nim. Możesz to rozważyć, jeśli musisz podać niestandardowy interfejs użytkownika nawigacji dla elementu Frame hostowanego w programie Window. Ponadto oba typy implementują dodatkowe elementy członkowskie związane z nawigacją, w tym BackStack (NavigationWindow.BackStack, Frame.BackStack) i ForwardStack (NavigationWindow.ForwardStack, Frame.ForwardStack), które umożliwiają wyliczanie wpisów dziennika w stosie wstecznym i stosie do przodu, odpowiednio.
Jak wspomniano wcześniej, w aplikacji może istnieć więcej niż jeden dziennik. Na poniższej ilustracji przedstawiono przykład tego, kiedy może się to zdarzyć.

Przechodzenie do zawartości innego niż strony XAML
W tym temacie Page i pakiet XBAPs zostały użyte do zademonstrowania różnych możliwości nawigacji WPF. Jednak Page element kompilowany w aplikacji nie jest jedynym typem zawartości, do którego można przejść, a pakowanie XBAPs nie jest jedynym sposobem identyfikowania zawartości.
Jak pokazano w tej sekcji, możesz również przejść do luźnych plików XAML, plików HTML i obiektów.
Przechodzenie do luźnych plików XAML
Luźny plik XAML jest plikiem o następujących cechach:
Zawiera tylko kod XAML (czyli bez kodu).
Ma odpowiednią deklarację przestrzeni nazw.
Ma rozszerzenie nazwy pliku xaml.
Rozważmy na przykład następującą zawartość przechowywaną jako luźny plik XAML Person.xaml.
<!-- 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>
Po dwukrotnym kliknięciu pliku przeglądarka zostanie otwarta i zostanie wyświetlona zawartość. Jest to pokazane na poniższej ilustracji.

Możesz wyświetlić luźny plik XAML z następujących elementów:
Witryna sieci Web na komputerze lokalnym, intranecie lub Internecie.
Udział plików UNC (Universal Naming Convention).
Dysk lokalny.
Luźny plik XAML można dodać do ulubionych przeglądarki lub być stroną główną przeglądarki.
Uwaga
Aby uzyskać więcej informacji na temat publikowania i uruchamiania luźnych stron XAML, zobacz Wdrażanie aplikacji WPF.
Jednym z ograniczeń dotyczących luźnego kodu XAML jest możliwość hostowania tylko zawartości, która jest bezpieczna do uruchamiania w częściowej relacji zaufania. Na przykład Window nie może być elementem głównym luźnego pliku XAML. Aby uzyskać więcej informacji, zobacz WPF Partial Trust Security (Zabezpieczenia częściowego zaufania WPF).
Przechodzenie do plików HTML przy użyciu ramki
Jak można się spodziewać, możesz również przejść do kodu HTML. Wystarczy podać identyfikator URI, który używa schematu HTTP. Na przykład poniższy kod XAML pokazuje element Frame , który przechodzi do strony HTML.
<Frame Source="http://www.microsoft.com/default.aspx" />
Przechodzenie do kodu HTML wymaga specjalnych uprawnień. Na przykład nie można przechodzić z sieci XBAP uruchomionej w strefie internetowej w piaskownicy zabezpieczeń częściowego zaufania. Aby uzyskać więcej informacji, zobacz WPF Partial Trust Security (Zabezpieczenia częściowego zaufania WPF).
Przechodzenie do plików HTML przy użyciu kontrolki WebBrowser
Kontrolka WebBrowser obsługuje hosting dokumentów HTML, nawigację i współdziałanie skryptów/kodu zarządzanego. Aby uzyskać szczegółowe informacje dotyczące kontrolki WebBrowser , zobacz WebBrowser.
Na przykład przechodzenie Framedo kodu HTML przy użyciu polecenia WebBrowser wymaga specjalnych uprawnień. Na przykład w aplikacji o częściowym zaufaniu można przejść tylko do kodu HTML znajdującego się w lokacji źródła. Aby uzyskać więcej informacji, zobacz WPF Partial Trust Security (Zabezpieczenia częściowego zaufania WPF).
Przechodzenie do obiektów niestandardowych
Jeśli masz dane przechowywane jako obiekty niestandardowe, jednym ze sposobów wyświetlenia tych danych jest utworzenie obiektu z zawartością powiązaną Page z tymi obiektami (zobacz Omówienie powiązania danych). Jeśli nie potrzebujesz nakładu pracy związanego z tworzeniem całej strony tylko w celu wyświetlenia obiektów, możesz przejść bezpośrednio do nich.
Rozważ klasę Person zaimplementowaną w poniższym kodzie.
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
Aby przejść do niej, wywołaj metodę NavigationWindow.Navigate , jak pokazano w poniższym kodzie.
<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
Na poniższej ilustracji przedstawiono rezultat.

Na tym rysunku widać, że nic nie jest przydatne. W rzeczywistości wyświetlana wartość jest zwracaną wartością ToString metody obiektu Person . Domyślnie jest to jedyna wartość, której WPF może użyć do reprezentowania obiektu. Można przesłonić metodę, ToString aby zwrócić bardziej znaczące informacje, chociaż nadal będzie to tylko wartość ciągu. Jedną z technik, których można użyć, która korzysta z możliwości prezentacji WPF, jest użycie szablonu danych. Można zaimplementować szablon danych, który WPF może skojarzyć z obiektem określonego typu. Poniższy kod przedstawia szablon danych dla Person obiektu .
<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>
W tym miejscu szablon danych jest skojarzony z typem Person przy użyciu x:Type rozszerzenia znaczników w atrybucie DataType . Następnie szablon danych wiąże TextBlock elementy (patrz TextBlock) z właściwościami Person klasy. Na poniższej ilustracji przedstawiono zaktualizowany wygląd Person obiektu.

Zaletą tej techniki jest spójność uzyskana dzięki możliwości ponownego użycia szablonu danych w celu spójnego wyświetlania obiektów w dowolnym miejscu w aplikacji.
Aby uzyskać więcej informacji na temat szablonów danych, zobacz Szablony danych — omówienie.
Zabezpieczenia
Obsługa nawigacji WPF umożliwia przechodzenie XBAPs do Internetu i umożliwia aplikacjom hostowanie zawartości innej firmy. Aby chronić zarówno aplikacje, jak i użytkowników przed szkodliwym zachowaniem, platforma WPF udostępnia różne funkcje zabezpieczeń omówione w temacie Zabezpieczenia iZabezpieczenia częściowego zaufania WPF.