Przegląd Nawigacja

Program 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 jednej Page do innej deklaratywnie, używając Hyperlinkmetody , lub programowo przy użyciu .NavigationService WPF używa dziennika do zapamiętania stron, które zostały nawigowane z i, aby wrócić do nich.

Page, , HyperlinkNavigationServicei dziennik tworzą rdzeń obsługi nawigacji oferowanej przez WPF. W tym omówieniu szczegółowo przedstawiono te funkcje 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 zawierają 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.

Ten temat zawiera omówienie kluczowych możliwości nawigacji w WPF. Te funkcje są dostępne zarówno dla autonomicznych aplikacji, 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 WPF można przejść do kilku typów zawartości, które obejmują obiekty programu .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 tworzenia pakietów zawartości jest użycie polecenia Page. Ponadto implementuje funkcje specyficzne dla nawigacji, Page aby zwiększyć ich wygląd i uprościć programowanie.

Za pomocą metody Pagemożna deklaracyjnie zaimplementować stronę z możliwością nawigacji zawartości XAML przy użyciu znaczników, takich jak poniżej.

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

Element Page implementowany w znaczników 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ć. Zawartość można dodać, 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 kontrolka układu jest zwykle używana jako element podrzędny (zobacz Układ) do przechowywania i redagowania zawartości.

Elementy podrzędne Page 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 tym przypadku Page.Content element jest ustawiany automatycznie z elementami podrzędnymi Page elementu. Aby uzyskać więcej informacji, zobacz Model zawartości WPF.

Do wyświetlania zawartości przydaje się tylko Page znaczniki. Można jednak również wyświetlać kontrolki, Page 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. Interakcyjne Page jest implementowane przy użyciu kombinacji znaczników i kodu, 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 code-behind, wymagana jest następująca konfiguracja:

  • W znacznikach element Page musi zawierać atrybut x:Class. Gdy aplikacja jest kompilowana, istnienie x:Class w pliku znaczników powoduje, że aparat microsoft build engine (MSBuild) tworzy klasę partial , która pochodzi z Page i ma nazwę określoną przez x:Class atrybut . Wymaga to dodania deklaracji przestrzeni nazw XML dla schematu XAML ( xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" ). Wygenerowana partial klasa implementuje InitializeComponentmetodę , która jest wywoływana w celu zarejestrowania zdarzeń i ustawienia właściwości implementowanych w adiustacji.

  • W pliku codebehind klasa musi być klasą partial o tej samej nazwie, która jest określona przez atrybut x:Class w znacznikach, i musi pochodzić z klasy Page. Dzięki temu plik za kodem może być skojarzony z klasą partial , która jest generowana dla pliku znaczników podczas kompilowania aplikacji (zobacz Tworzenie aplikacji WPF).

  • W pliku codebehind klasa Page musi zaimplementować konstruktora, który wywołuje metodę InitializeComponent. Metoda InitializeComponent jest implementowana przez wygenerowaną klasę partial pliku znaczników w celu rejestrowania zdarzeń i ustawiania właściwości zdefiniowanych w znacznikach.

Uwaga

Po dodaniu nowego Page elementu do projektu przy użyciu programu Visual Studio Page implementacja jest implementowana przy użyciu zarówno znaczników, jak i kodu za pomocą kodu, i obejmuje konfigurację niezbędną do utworzenia skojarzenia między znacznikami i plikami za pomocą kodu zgodnie z opisem w tym miejscu.

Po utworzeniu elementu Pagemożesz przejść do niego. Aby określić pierwszy, do którego Page przechodzi aplikacja, należy skonfigurować uruchamianie Page.

Konfigurowanie strony początkowej

XBAPs wymagają, aby w przeglądarce była hostowana pewna ilość infrastruktury aplikacji. W 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ć jej definicji aplikacji, aby określić początek Page, który jest Page automatycznie ładowany po uruchomieniu XBAP. W tym celu należy ustawić StartupUri właściwość przy użyciu identyfikatora URI (Uniform Resource Identifier) dla żądanego Pageelementu .

Uwaga

W większości przypadków element Page jest kompilowany w aplikacji lub wdrażany z aplikacją. W takich przypadkach identyfikator URI identyfikujący 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 Pack URIs in WPF (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żna 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 identyfikującego plik HomePage.xaml. Po uruchomieniu XBAP plik HomePage.xaml jest automatycznie przechodzi do i wyświetlany. Jest to pokazane na poniższym rysunku, który pokazuje XBAP, który został uruchomiony z serwera sieci Web.

XBAP page

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 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ł zarówno przeglądarki, jak i panelu karty jest identyfikatorem URI XBAP. Oprócz długiego tytułu 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 znaczników, 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 przedstawiono na poniższej ilustracji.

Window title, height, width

Typowy XBAP składa się z kilku stron. Najprostszym sposobem nawigowania między stronami 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 elementu Page , do który ma przejść, zgodnie z opisem atrybutu NavigateUri .

  • Zawartość, którą użytkownik może kliknąć, aby zainicjować nawigację, taką jak tekst i obrazy (dla zawartości, którą Hyperlink może zawierać element, zobacz Hyperlink).

Na poniższej ilustracji przedstawiono XBAP z elementem Page o wartości Hyperlink.

Page with Hyperlink

Jak można się spodziewać, kliknięcie Hyperlink powoduje przejście XBAP do Page elementu, który jest identyfikowany przez NavigateUri atrybut. Ponadto XBAP dodaje wpis poprzedniej Page listy Ostatnie strony w programie Internet Explorer. Jest to pokazane na poniższym rysunku.

Back and Forward buttons

Oprócz obsługi nawigacji między sobą Page , Hyperlink obsługuje również nawigację fragmentów.

Nawigacja po fragmentach

Nawigacja po fragmentach to nawigacja do fragmentu zawartości w bieżącym lub innym Pageelemencie 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 zawierający 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>

Aby przejść Hyperlink do fragmentu zawartości, NavigateUri atrybut musi zawierać następujące elementy:

  • Identyfikator URI obiektu Page z fragmentem zawartości do przejścia.

  • Znak "#".

  • Nazwa elementu w obiekcie Page zawierającym fragment zawartości.

Identyfikator URI fragmentu ma następujący format.

PageURI#, nazwa elementu

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 fragmentów w WPF. WPF umożliwia również zaimplementowanie własnego schematu nawigacji fragmentów, który częściowo wymaga obsługi NavigationService.FragmentNavigation zdarzenia.

Ważne

Możesz przechodzić do fragmentów na luźnych stronach XAML (pliki XAML tylko znaczniki 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 przejść do własnych fragmentów.

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.

Kliknięcie elementu Hyperlink spowoduje wywołanie WPF NavigationService.Navigate w celu zlokalizowania i pobrania identyfikatora Page URI określonego pakietu. Pobrany Page obiekt jest konwertowany 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ła wyświetlona, 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

Istnieje możliwość, aby aplikacja WPF miała więcej niż jeden aktualnie aktywny NavigationServiceelement . Aby uzyskać więcej informacji, zobacz Hosty nawigacji w dalszej części tego tematu.

Programowa nawigacja za pomocą usługi nawigacji

Nie musisz wiedzieć, NavigationService czy nawigacja jest implementowana deklaratywnie w adiustacji przy użyciu metody 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źć i użyć usługi nawigacji hosta nawigacji do przetworzenia żądania nawigacji.

Istnieją jednak sytuacje, w których należy użyć NavigationService bezpośrednio, w tym następujące kwestie:

  • W przypadku konieczności utworzenia Page wystąpienia obiektu przy użyciu konstruktora bez parametrów.

  • Gdy musisz ustawić właściwości przed Page 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 w celu programowego zainicjowania nawigacji 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 przechodzi NavigationService do bieżącego Pageelementu . Odwołanie do obiektu NavigationService można uzyskać, wywołując metodę staticNavigationService.GetNavigationService . Aby uzyskać element NavigationService , który przechodzi do określonego Pageelementu , należy przekazać odwołanie do Page metody jako argument metody GetNavigationService . 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 następującym 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 elementu NavigationService , gdy Page zgłasza Loaded zdarzenie.

Programowa nawigacja do obiektu strony

W poniższym przykładzie pokazano, jak NavigationService programowo przejść do elementu Page. Nawigacja programowa jest wymagana, ponieważ Page jest on przenoszony do programu można utworzyć tylko przy użyciu jednego, nieparametrowego konstruktora. Element Page z konstruktorem bez parametrów jest wyświetlany w poniższym znaczników 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

Element Page , który przechodzi do Page klasy z konstruktorem bez parametrów, jest wyświetlany w poniższym znaczniku 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, a nie identyfikator URI pakietu.

Programowa nawigacja przy użyciu identyfikatora URI pakietu

Jeśli musisz skonstruować identyfikator URI pakietu programowo (gdy można określić tylko identyfikator URI pakietu w czasie wykonywania), możesz użyć NavigationService.Navigate metody . Jest to pokazane w następującym 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

Obiekt 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 przez 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

Istnieje wiele sposobów inicjowania nawigacji, jak pokazano wcześniej. Gdy nawigacja jest inicjowana, a nawigacja jest w toku, można śledzić i wpływać na nawigację przy użyciu następujących zdarzeń implementowanych przez NavigationServiceprogram :

  • Navigating. Występuje po zażądaniu nowej nawigacji. Może służyć do anulowania nawigacji.

  • NavigationProgress. Występuje okresowo podczas pobierania, aby zapewnić informacje o postępie nawigacji.

  • Navigated. Występuje po zlokalizowaniu i pobraniu strony.

  • 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 po wystąpieniu błędu podczas przechodzenia do żądanej zawartości.

  • 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, gdy rozpoczyna się nawigacja 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ę.

Page navigation flow chart

Ogólnie rzecz biorąc, element Page nie jest zaniepokojony tymi zdarzeniami. Jest bardziej prawdopodobne, że aplikacja jest z nimi zaniepokojona i z tego powodu te zdarzenia są również wywoływane 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, aby wykrywać nawigację w odpowiednich zakresach.

W niektórych przypadkach Page może być zainteresowany tymi zdarzeniami. Na przykład może Page obsłużyć NavigationService.Navigating zdarzenie, aby określić, czy anulować nawigację z dala od siebie. Jest to pokazane w następującym 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 Pageobiektu , jak pokazano 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

WPF używa dwóch stosów do zapamiętania stron, z których przechodzisz: stosu wstecznego i stosu do przodu. Po przejściu z bieżącego Page do nowego Page lub do przodu do istniejącego Page, bieżący Page zostanie dodany do stosu wstecznego. Po przejściu z bieżącego Page z powrotem do poprzedniego Pageelementu bieżący Page jest dodawany do stosu przekazywania dalej. Stos wsteczny, stos do przodu i funkcje do zarządzania nimi są zbiorczo określane jako dziennik. Każdy element w stosie wstecznym i stosie przesyłania dalej jest wystąpieniem JournalEntryklasy i jest określany jako wpis dziennika.

Koncepcyjnie dziennik działa w taki sam sposób, jak przyciski Wstecz i Prześlij dalej w programie Internet Explorer. Przedstawiono je na poniższej ilustracji.

Back and Forward buttons

W przypadku protokołu XBAPs, które są hostowane 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 przy użyciu 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 dla każdego Page , który jest wyświetlany na liście Ostatnie strony programu Internet Explorer, to identyfikator URI 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:

  1. Dołączona JournalEntry.Name wartość atrybutu.

  2. Wartość atrybutu Page.Title .

  3. Wartość Page.WindowTitle atrybutu i identyfikator URI dla bieżącego Pageelementu .

  4. Identyfikator URI bieżącego Pageelementu . (Domyślna)

Kolejność wyświetlania opcji jest zgodna z kolejnością pierwszeństwa podczas znajdowania tekstu. Jeśli na przykład JournalEntry.Name jest ustawiona, inne 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

Mimo że użytkownik może nawigować po dzienniku przy użyciu funkcji Wstecz, Prześlij dalej i Ostatnie strony 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>

Dziennik można programowo nawigować 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

Należy wziąć pod uwagę 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, które zostały przekazane, 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żda Page nawigacja ma okres istnienia ilustrowany przez poniższą ilustrację.

Page lifetime

Mimo że użycie domyślnego zachowania dziennika może zaoszczędzić na użyciu pamięci, wydajność renderowania na stronie może być 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 zachowuje wystąpienie Page klasy 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 znacznikach.

<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 element Page , który jest utrzymywany przy życiu, jest nawigowany, jest tworzone tak samo jak to Page , które nie jest utrzymywane przy życiu. Jednak ze względu na to, że wystąpienie Page obiektu 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 nastąpi przejście do obiektu , należy przenieść go z konstruktora do procedury obsługi dla Loaded zdarzenia. Jak pokazano na poniższej ilustracji, Loaded zdarzenia i Unloaded są nadal wywoływane za każdym razem, gdy Page następuje przejście do i z , odpowiednio.

When the Loaded and Unloaded events are raised

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ń przy użyciu zdarzeń, które nie są przez nią implementowane.

Wykonanie jednej z tych czynności spowoduje utworzenie odwołań, które wymuszą Page zachowanie w pamięci, nawet po usunięciu z dziennika.

Ogólnie rzecz biorąc, należy preferować domyślne Page zachowanie, aby nie utrzymywać Page aktywności. Jednak ma to wpływ na stan, które zostały omówione w następnej sekcji.

Zachowywanie stanu zawartości przy użyciu historii 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 Pageobiektu ? Z perspektywy środowiska użytkownika użytkownik powinien oczekiwać, że dane wprowadzone wcześniej. Niestety, ponieważ nowe wystąpienie obiektu Page jest tworzone z każdą nawigacją, kontrolki, które zebrały dane, są potwierdzane i dane zostaną utracone.

Na szczęście dziennik zapewnia obsługę zapamiętowania danych między Page nawigacjami, w tym danych kontrolnych. W szczególności wpis dziennika dla każdego Page działa jako tymczasowy kontener dla skojarzonego Page stanu. W poniższych krokach opisano sposób użycia tej obsługi podczas Page nawigowania z:

  1. Wpis dla bieżącego Page jest dodawany do dziennika.

  2. Stan Page obiektu jest przechowywany z wpisem dziennika dla tej strony, który jest dodawany do stosu wstecznego.

  3. Page Nowy jest przechodziny do.

Po powrocie do strony Page , korzystając z dziennika, należy wykonać następujące czynności:

  1. Element Page (górny wpis dziennika na stosie wstecznym) jest tworzone wystąpienie.

  2. Jest Page odświeżany ze stanem, który był przechowywany z wpisem dziennika dla Page.

  3. Element Page zostanie przywrócony do.

WPF automatycznie używa tej obsługi, gdy następujące kontrolki są używane w elemecie Page:

Page Jeśli używa tych kontrolek, wprowadzone w nich dane są zapamiętywane w Page nawigacji, jak pokazano na rysunku UlubionymListBox kolorem.

Page with controls that remember state

Jeśli element Page zawiera kontrolki inne niż te na powyższej liście lub gdy stan jest przechowywany w obiektach niestandardowych, należy napisać kod, aby spowodować, że dziennik zapamięta stan w Page nawigacji.

Jeśli musisz pamiętać małe fragmenty stanu w Page nawigacji, możesz użyć właściwości zależności (zobacz DependencyProperty) skonfigurowanych z flagą 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 korzystający z kodu, aby hermetyzować stan w jednej klasie i zaimplementować IProvideCustomContentState interfejs.

Jeśli musisz przechodzić przez różne stany pojedynczego Pageelementu , bez przechodzenia od Page samego siebie, możesz użyć polecenia 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 w różnych sesjach aplikacji. Dane plików cookie zwykle mają postać pary nazwa/wartość w następującym formacie.

Wartość nazwy=

Po przekazaniu danych do SetCookieelementu 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 Tymczasowe pliki internetowe systemu Windows bieżącej instalacji systemu Windows do momentu wygaśnięcia pliku cookie. Taki plik cookie jest nazywany trwałym plikiem cookie , ponieważ utrzymuje się w sesjach 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.

  • Pliki cookie tworzone przez XBAP można uzyskać w przeglądarce.

  • 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 pliki 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 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 klasy 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 metody , 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 elementu, do którego Page nastąpi przejście. Problem polega na tym, że nawigacja nie obsługuje natywnie mechanizmów zagwarantowania, że element Page 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 element Page jest zwracany w przewidywalny i ustrukturyzowany sposób. Aby uzyskać więcej informacji, zobacz Omówienie nawigacji strukturalnej.

Klasa NavigationWindow

W tym momencie opisano gamę usług nawigacji, których najprawdopodobniej używasz do tworzenia aplikacji z zawartością z możliwością nawigacji. Te usługi zostały omówione w kontekście XBAPs, chociaż nie są one ograniczone do XBAPs. Nowoczesne systemy operacyjne i aplikacje systemu Windows korzystają ze środowiska przeglądarki nowoczesnych użytkowników w celu włączenia nawigacji w stylu przeglądarki do autonomicznych aplikacji. Do powszechnych przykładów należą:

  • Word 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 składników systemu Windows, który obsługuje dodawanie i usuwanie funkcji systemu Windows.

Aby włączyć nawigację w stylu przeglądarki do autonomicznych aplikacji, możesz użyć NavigationWindow klasy . NavigationWindow 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 (Windowitd Page.), należy użyć kombinacji znaczników i kodu. Jest to pokazane w następującym 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.

A main window

Na rysunku widać, że NavigationWindow element 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>

Ustawienie właściwości WindowWidth i WindowHeight wpływa również na NavigationWindowelement .

Zazwyczaj implementujesz własne NavigationWindow , gdy musisz 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 automatycznie utworzy element NavigationWindow do hostowania obiektu Page. Poniższy znacznik pokazuje, jak to włączyć.

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

Jeśli chcesz, aby dodatkowe okno aplikacji, 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.

A dialog box

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.

Back and Forward buttons in a NavigationWindow

Jeśli strony zapewniają własną obsługę nawigacji dziennika 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żesz użyć obsługi dostosowywania w WPF, aby zastąpić interfejs użytkownika NavigationWindow samego siebie.

Klasa ramki

Zarówno w przeglądarce, jak i NavigationWindow oknach hostujących 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ści. 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 z identyfikatorem URI pakietu, do Page którego Frame powinien początkowo przejść. Na poniższej ilustracji przedstawiono znak XBAP z elementem PageFrame , który przechodzi między kilkoma stronami.

A frame that has navigated between multiple pages

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 tylko używa własnego dziennika w przypadku braku innego dziennika. Jeśli element Frame jest częścią zawartości hostowanej wewnątrz elementu 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ę dziennika na stronach hostowanych przez element Frame. Jest to zilustrowane na poniższym rysunku.

Frame and Page diagram

W takim przypadku można skonfigurować element 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 korzystającego Frame z własnego dziennika.

A frame that uses its own journal

Zwróć uwagę, że wpisy dziennika są wyświetlane przez interfejs użytkownika nawigacji w programie Frame, a nie przez program 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ść NavigationUIVisibilityHiddenna . 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>

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 dziennika. Podstawowa konstrukcja hosta nawigacji jest pokazana na poniższej ilustracji.

Navigator diagrams

Zasadniczo pozwala to i NavigationWindowFrame zapewnić taką samą obsługę nawigacji, jaką zapewnia 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.

A journal in a Frame and in a NavigationWindow

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 zaplecza 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ć.

Multiple journals within one application

W tym temacie Page i pakiet XBAPs zostały użyte do zademonstrowania różnych możliwości nawigacji WPF. Jednak Page skompilowany w aplikacji nie jest jedynym typem zawartości, do którego można przejść, a pakiet 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.

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 i wyświetlona zawartość. Jest to pokazane na poniższym rysunku.

Display of the content in the Person.XAML file

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 to, że można hostować tylko zawartość, która jest bezpieczna do uruchamiania w częściowym zaufaniu. Na przykład Window nie może być elementem głównym luźnego pliku XAML. Aby uzyskać więcej informacji, zobacz Zabezpieczenia częściowego zaufania WPF.

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 przedstawia element Frame , który przechodzi do strony HTML.

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

Przejście do kodu HTML wymaga specjalnych uprawnień. Na przykład nie można nawigować z dysku XBAP uruchomionego w piaskownicy zabezpieczeń częściowego zaufania strefy internetowej. Aby uzyskać więcej informacji, zobacz Zabezpieczenia częściowego zaufania WPF.

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 Frameprzechodzenie do kodu HTML przy użyciu polecenia WebBrowser wymaga specjalnych uprawnień. Na przykład z poziomu aplikacji częściowo zaufanej można przejść tylko do kodu HTML znajdującego się w lokacji źródła. Aby uzyskać więcej informacji, zobacz Zabezpieczenia częściowego zaufania WPF.

Jeśli masz dane przechowywane jako obiekty niestandardowe, jednym ze sposobów wyświetlania 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.

A page that navigates to a class

Na tym rysunku widać, że nic przydatnego nie jest wyświetlane. 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 zastąpić 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.

Navigating to a class that has a data template

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 Omówienie tworzenia szablonów danych.

Zabezpieczenia

Obsługa nawigacji WPF umożliwia przechodzenie do protokołu XBAPs przez Internet 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 i Zabezpieczenia częściowego zaufania WPF.

Zobacz też