Visão geral de navegação

O Windows Presentation Foundation (WPF) oferece suporte à navegação no estilo de navegador que pode ser usada em dois tipos de aplicativos: aplicativos autônomos e aplicativos de navegador XAML (XBAPs). Para empacotar o conteúdo para navegação, o WPF fornece a Page classe. Você pode navegar de um para outro declarativamente, usando um PageHyperlink, ou programaticamente, usando o NavigationService. O WPF usa o diário para lembrar páginas que foram navegadas e navegar de volta para elas.

PageNavigationService, , Hyperlinke o diário formam o núcleo do suporte de navegação oferecido pelo WPF. Esta visão geral explora esses recursos em detalhes antes de abordar o suporte avançado à navegação que inclui navegação para arquivos XAML (Extensible Application Markup Language), arquivos HTML e objetos soltos.

Observação

Neste tópico, o termo "navegador" refere-se apenas a navegadores que podem hospedar aplicativos WPF, que atualmente inclui o Microsoft Internet Explorer e o Firefox. Quando recursos específicos do WPF são suportados apenas por um navegador específico, a versão do navegador é mencionada.

Este tópico fornece uma visão geral dos principais recursos de navegação no WPF. Esses recursos estão disponíveis para aplicativos autônomos e XBAPs, embora este tópico os apresente no contexto de um XBAP.

Observação

Este tópico não discute como criar e implantar XBAPs. Para obter mais informações sobre XBAPs, consulte Visão geral de aplicativos de navegador XAML do WPF.

Esta seção explica e demonstra os seguintes aspectos da navegação:

Implementar uma página

No WPF, você pode navegar para vários tipos de conteúdo que incluem objetos do .NET Framework, objetos personalizados, valores de enumeração, controles de usuário, arquivos XAML e arquivos HTML. No entanto, você descobrirá que a maneira mais comum e conveniente de empacotar conteúdo é usando Pageo . Além disso, Page implementa recursos específicos de navegação para melhorar sua aparência e simplificar o desenvolvimento.

Usando Pageo , você pode implementar declarativamente uma página navegável de conteúdo XAML usando uma marcação como a seguinte.

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

Um Page que é implementado na marcação XAML tem Page como seu elemento raiz e requer a declaração de namespace XML WPF. O Page elemento contém o conteúdo que você deseja navegar e exibir. Você adiciona conteúdo definindo o Page.Content elemento de propriedade, conforme mostrado na marcação a seguir.

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

Page.Content só pode conter um elemento filho; no exemplo anterior, o conteúdo é uma única cadeia de caracteres, "Olá, Página!" Na prática, você geralmente usará um controle de layout como o elemento filho (consulte Layout) para conter e compor seu conteúdo.

Os elementos filho de um elemento são considerados o conteúdo de um PagePage e, consequentemente, você não precisa usar a declaração explícita Page.Content . A marcação a seguir é o equivalente declarativo da amostra anterior.

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

Nesse caso, Page.Content é definido automaticamente com os elementos filho do Page elemento. Para obter mais informações, consulte Modelo de conteúdo do WPF.

Uma marcação somente Page é útil para exibir conteúdo. No entanto, um Page também pode exibir controles que permitem que os usuários interajam com a página e pode responder à interação do usuário manipulando eventos e chamando a lógica do aplicativo. Um interativo Page é implementado usando uma combinação de marcação e code-behind, conforme mostrado no exemplo a seguir.

<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

Para permitir que um arquivo de marcação e o arquivo code-behind funcionem juntos, a seguinte configuração é necessária:

  • Na marcação, o elemento Page deve incluir o atributo x:Class. Quando o aplicativo é criado, a existência de no arquivo de marcação faz com que o mecanismo de compilação da Microsoft (MSBuild) crie uma partial classe que deriva de x:ClassPage e tem o nome especificado pelo x:Class atributo. Isso requer a adição de uma declaração de namespace XML para o esquema XAML ( xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" ). A classe gerada partial implementa InitializeComponent, que é chamado para registrar os eventos e definir as propriedades que são implementadas na marcação.

  • No code-behind, a classe deve ser uma classe partial com o mesmo nome que é especificado pelo atributo x:Class na marcação e ela deve derivar de Page. Isso permite que o arquivo code-behind seja associado à partial classe gerada para o arquivo de marcação quando o aplicativo é criado (consulte Criando um aplicativo WPF).

  • No code-behind, a classe Page deve implementar um construtor que chame o método InitializeComponent. InitializeComponent é implementado pela classe partial gerada pelo arquivo de marcação para registrar eventos e definir propriedades que são definidas na marcação.

Observação

Quando você adiciona um novo Page ao seu projeto usando o Visual Studio, o Page é implementado usando marcação e code-behind e inclui a configuração necessária para criar a associação entre os arquivos de marcação e code-behind, conforme descrito aqui.

Depois de ter um Page, você pode navegar até ele. Para especificar o primeiro Page para o qual um aplicativo navega, você precisa configurar o início Page.

Configurar uma página inicial

XBAPs exigem uma certa quantidade de infraestrutura de aplicativos para ser hospedado em um navegador. No WPF, a classe faz parte de uma definição de aplicativo que estabelece a Application infraestrutura de aplicativo necessária (consulte Visão geral do gerenciamento de aplicativos).

Uma definição de aplicativo geralmente é implementada usando marcação e code-behind, com o arquivo de marcação configurado como um item do MSBuildApplicationDefinition . A seguir está uma definição de aplicativo para um 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

Um XBAP pode usar sua definição de aplicativo para especificar um início Page, que é o que é carregado automaticamente quando o Page XBAP é iniciado. Para fazer isso, defina a StartupUri propriedade com o identificador uniforme de recursos (URI) para o Page.

Observação

Na maioria dos casos, o é compilado ou implantado Page com um aplicativo. Nesses casos, o URI que identifica um é um URI de pacote, que é um Page URI que está em conformidade com o esquema de pacote . Os URIs de pacote são discutidos mais adiante em URIs de pacote no WPF. Você também pode navegar para o conteúdo usando o esquema http, que é discutido abaixo.

Você pode definir StartupUri declarativamente na marcação, conforme mostrado no exemplo a seguir.

<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" />

Neste exemplo, o StartupUri atributo é definido com um URI de pacote relativo que identifica HomePage.xaml. Quando o XBAP é iniciado, HomePage.xaml é automaticamente navegado e exibido. Isso é demonstrado pela figura a seguir, que mostra um XBAP que foi iniciado a partir de um servidor Web.

XBAP page

Observação

Para obter mais informações sobre o desenvolvimento e a implantação de XBAPs, consulte Visão geral de aplicativos de navegador XAML do WPF e Implantando um aplicativo WPF.

Configurar o título, largura e altura da janela do host

Uma coisa que você deve ter notado na figura anterior é que o título do navegador e do painel de guias é o URI para o XBAP. Além de ser longo, o título não é atraente nem informativo. Por esse motivo, Page oferece uma maneira de você alterar o título definindo o WindowTitle imóvel. Além disso, você pode configurar a largura e a altura da janela do navegador definindo WindowWidth e WindowHeight, respectivamente.

WindowTitle, e WindowHeight pode ser definido declarativamente na marcação, WindowWidthconforme mostrado no exemplo a seguir.

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

O resultado é mostrado na figura a seguir.

Window title, height, width

Um XBAP típico compreende várias páginas. A maneira mais simples de navegar de uma página para outra é usar um Hyperlinkarquivo . Você pode adicionar declarativamente um Hyperlink a a usando o Hyperlink elemento , que é mostrado na marcação a Page seguir.

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

Um Hyperlink elemento requer o seguinte:

  • O URI do pacote para Page o qual navegar, conforme especificado pelo NavigateUri atributo.

  • Conteúdo no qual um usuário pode clicar para iniciar a navegação, como texto e imagens (para o conteúdo que o Hyperlink elemento pode conter, consulte Hyperlink).

A figura a seguir mostra um XBAP com um que tem um PageHyperlinkarquivo .

Page with Hyperlink

Como seria de esperar, clicar no Hyperlink faz com que o XBAP navegue até o Page que é identificado pelo NavigateUri atributo. Além disso, o XBAP adiciona uma entrada para o anterior Page para a lista de páginas recentes no Internet Explorer. Isso será mostrado na figura a seguir.

Back and Forward buttons

Além de suportar a navegação de um Page para outro, Hyperlink também suporta navegação por fragmentos.

Navegação de fragmento

A navegação de fragmento é a navegação para um fragmento de conteúdo no atual Page ou em outro Page. No WPF, um fragmento de conteúdo é o conteúdo contido por um elemento nomeado. Um elemento nomeado é um elemento que tem seu Name atributo definido. A marcação a seguir mostra um elemento nomeado TextBlock que contém um fragmento de conteúdo.

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

Para que um navegue até um Hyperlink fragmento de conteúdo, o atributo deve incluir o NavigateUri seguinte:

  • O URI do com o fragmento de Page conteúdo para o qual navegar.

  • Um caractere "#".

  • O nome do elemento no que contém o fragmento Page de conteúdo.

Um URI de fragmento tem o seguinte formato.

PageURI#ElementName

A seguir é mostrado um exemplo de um que está configurado para navegar até um Hyperlink fragmento de conteúdo.

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

Observação

Esta seção descreve a implementação de navegação de fragmento padrão no WPF. O WPF também permite que você implemente seu próprio esquema de navegação de fragmento que, em parte, requer a manipulação do NavigationService.FragmentNavigation evento.

Importante

Você pode navegar até fragmentos em páginas XAML soltas (arquivos XAML somente de marcação com Page como elemento raiz) somente se as páginas puderem ser navegadas via HTTP.

No entanto, uma página XAML solta pode navegar até seus próprios fragmentos.

Enquanto Hyperlink permite que um usuário inicie a navegação para um determinado Page, o trabalho de localizar e baixar a página é realizado pela NavigationService classe. Essencialmente, fornece a capacidade de processar uma solicitação de navegação em nome do código do cliente, NavigationService como o Hyperlink. Além disso, NavigationService implementa suporte de nível superior para rastrear e influenciar uma solicitação de navegação.

Quando um Hyperlink é clicado, o WPF chama NavigationService.Navigate para localizar e baixar o Page URI do pacote especificado. O download Page é convertido em uma árvore de objetos cujo objeto raiz é uma instância do download Page. Uma referência ao objeto raiz Page é armazenada na NavigationService.Content propriedade. O URI do pacote para o conteúdo que foi navegado é armazenado na NavigationService.Source propriedade, enquanto o armazena o NavigationService.CurrentSource URI do pacote para a última página para a qual foi navegado.

Observação

É possível que um aplicativo WPF tenha mais de um ativo NavigationServiceno momento. Para obter mais informações, consulte Hosts de navegação posteriormente neste tópico.

Navegação programática com o serviço de navegação

Você não precisa saber se NavigationService a navegação é implementada declarativamente na marcação usando Hyperlink, porque Hyperlink usa o NavigationService em seu nome. Isso significa que, desde que o pai direto ou indireto de um seja um Hyperlink host de navegação (consulte Hosts de navegação), Hyperlink poderá localizar e usar o serviço de navegação do host de navegação para processar uma solicitação de navegação.

No entanto, há situações em que você precisa usar NavigationService diretamente, incluindo o seguinte:

  • Quando você precisa instanciar um usando um Page construtor sem parâmetros.

  • Quando você precisar definir propriedades no antes de Page navegar até ele.

  • Quando o Page que precisa ser navegado para só pode ser determinado em tempo de execução.

Nessas situações, você precisa escrever código para iniciar programaticamente a navegação chamando o NavigateNavigationService método do objeto. Para isso, é necessário obter uma referência a um NavigationServicearquivo .

Obter uma referência para o NavigationService

Por motivos abordados na seção Hosts de navegação , um aplicativo WPF pode ter mais de um NavigationService. Isso significa que seu código precisa de uma maneira de encontrar um NavigationService, que geralmente é o que navegou para o NavigationService .Page Você pode obter uma referência a um NavigationService chamando o staticNavigationService.GetNavigationService método. Para obter o que navegou para um determinado Page, você passa uma referência para o como o NavigationServicePage argumento do GetNavigationService método. O código a seguir mostra como obter o para o NavigationService .Page

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)

Como um atalho para encontrar o foro NavigationServicePage, Page implementa a NavigationService propriedade. Isso é mostrado no exemplo a seguir.

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

Observação

A Page só pode obter uma referência a sua NavigationService quando Page levanta o Loaded evento.

Navegação programática para um objeto de página

O exemplo a seguir mostra como usar o NavigationService para navegar programaticamente até um Pagearquivo . A navegação programática é necessária porque o que está sendo navegado para o Page qual está sendo navegado só pode ser instanciado usando um único construtor sem parâmetros. O Page construtor with the non-parameterless é mostrado na marcação e no código a seguir.

<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

O Page que navega para o com o Page construtor non-parameterless é mostrado na marcação e código a seguir.

<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

Quando o on é Page clicado, a navegação é iniciada instanciando o para navegar usando o construtor sem parâmetros e chamando o HyperlinkPageNavigationService.Navigate método. Navigate aceita uma referência ao objeto para o qual o NavigationService irá navegar, em vez de um URI de pacote.

Navegação programática com um URI "pack://"

Se você precisar construir um URI de pacote programaticamente (quando você só pode determinar o URI do pacote em tempo de execução, por exemplo), você pode usar o NavigationService.Navigate método. Isso é mostrado no exemplo a seguir.

<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

Atualizar a página atual

Um Page não será baixado se tiver o mesmo URI do pacote que o URI do pacote armazenado na NavigationService.Source propriedade. Para forçar o WPF a baixar a página atual novamente, você pode chamar o NavigationService.Refresh método, conforme mostrado no exemplo a seguir.

<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

Como você viu, há várias maneiras de iniciar a navegação. Quando a navegação é iniciada e enquanto a navegação está em andamento, você pode controlar e influenciar a navegação usando os seguintes eventos que são implementados por NavigationService:

  • Navigating. Ocorre quando uma nova navegação é solicitada. Pode ser usado para cancelar a navegação.

  • NavigationProgress. Ocorre periodicamente durante um download para fornecer informações sobre o andamento da navegação.

  • Navigated. Ocorre quando a página foi localizada e baixada.

  • NavigationStopped. Ocorre quando a navegação é interrompida (chamando StopLoading) ou quando uma nova navegação é solicitada enquanto uma navegação atual está em andamento.

  • NavigationFailed. Ocorre quando um erro é gerado ao negar para o conteúdo solicitado.

  • LoadCompleted. Ocorre após carregar, analisar o conteúdo para o qual se navegou e iniciar sua renderização.

  • FragmentNavigation. Ocorre quando a navegação para um fragmento de conteúdo começa, o que ocorre:

    • Imediatamente, se o fragmento desejado estiver no conteúdo atual.

    • Depois que o conteúdo de origem tiver sido carregado, se o fragmento desejado estiver em outro conteúdo.

Os eventos de navegação são acionados na ordem em que são ilustrados pela figura a seguir.

Page navigation flow chart

Em geral, a não Page está preocupada com esses eventos. É mais provável que um aplicativo esteja preocupado com eles e, por essa razão, esses eventos também são levantados Application pela classe:

Toda vez que NavigationService levanta um evento, a Application classe levanta o evento correspondente. Frame e NavigationWindow oferecer os mesmos eventos para detectar a navegação dentro de seus respectivos escopos.

Em alguns casos, um Page pode estar interessado nesses eventos. Por exemplo, um Page pode manipular o evento para determinar se deve ou não cancelar a NavigationService.Navigating navegação longe de si mesmo. Isso é mostrado no exemplo a seguir.

<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

Se você registrar um manipulador com um evento de navegação de um Page, como faz o exemplo anterior, também deverá cancelar o registro do manipulador de eventos. Se você não fizer isso, pode haver efeitos colaterais com relação a como a navegação do WPF lembra Page a navegação usando o diário.

Memorizar a navegação com o diário

O WPF usa duas pilhas para lembrar as páginas das quais você navegou: uma pilha traseira e uma pilha direta. Quando você navega da corrente para uma nova Page ou para frente para uma existentePage, a corrente PagePage é adicionada à pilha traseira. Quando você navega da corrente de volta para a anteriorPage, a corrente PagePage é adicionada à pilha de encaminhamento. Nos referimos ao conjunto composto pela pilha voltar, a pilha avançar e a funcionalidade para gerenciá-las como o diário. Cada item na pilha traseira e na pilha direta é uma instância da classe e é referido como uma entrada de JournalEntry diário.

Conceitualmente, o diário opera da mesma maneira que os botões Voltar e Avançar no Internet Explorer. Eles serão mostrados na figura a seguir.

Back and Forward buttons

Para XBAPs hospedados pelo Internet Explorer, o WPF integra o diário à interface do usuário de navegação do Internet Explorer. Isso permite que os usuários naveguem por páginas em um XBAP usando os botões Voltar, Encaminhar e Páginas Recentes no Internet Explorer.

Importante

No Internet Explorer, quando um usuário navega para fora e de volta para um XBAP, somente as entradas de diário para páginas que não foram mantidas ativas são mantidas no diário. Para discussão sobre como manter páginas ativas, consulte Tempo de vida da página e o diário mais adiante neste tópico.

Por padrão, o texto de cada Page um que aparece na lista Páginas Recentes do Internet Explorer é o URI Pagedo . Em muitos casos, isso não é especialmente significativo para o usuário. Felizmente, você pode alterar o texto usando uma das seguintes opções:

  1. O valor do atributo anexado JournalEntry.Name .

  2. O Page.Title valor do atributo.

  3. O Page.WindowTitle valor do atributo e o URI do .Page

  4. O URI do .Page (Padrão)

A ordem na qual as opções estão listadas coincide com a ordem de precedência para localizar o texto. Por exemplo, se JournalEntry.Name for definido, os outros valores serão ignorados.

O exemplo a seguir usa o atributo para alterar o Page.Title texto que aparece para uma entrada de diário.

<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

Embora um usuário possa navegar no diário usando as Páginas Voltar, Avançar e Recentes no Internet Explorer, você também pode navegar no diário usando mecanismos declarativos e programáticos fornecidos pelo WPF. Uma razão para fazer isso é fornecer interfaces de usuário de navegação personalizadas em suas páginas.

Você pode adicionar declarativamente o suporte à navegação do diário usando os comandos de navegação expostos pelo NavigationCommands. O exemplo a seguir demonstra como usar o BrowseBack comando navigation.

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

Você pode navegar programaticamente no diário usando um dos seguintes membros da NavigationService classe:

O diário também pode ser manipulado programaticamente, conforme discutido em Reter o estado de conteúdo com histórico de navegação, mais adiante neste tópico.

Tempo de vida da página e o diário

Considere um XBAP com várias páginas que contêm conteúdo rico, incluindo gráficos, animações e mídia. O volume de memória de páginas como essas poderá ser muito grande, especialmente se mídia de áudio e vídeo for usada. Dado que o diário "lembra" páginas que foram navegadas, tal XBAP poderia rapidamente consumir uma grande e perceptível quantidade de memória.

Por esse motivo, o comportamento padrão do diário é armazenar Page metadados em cada entrada de diário em vez de uma referência a um Page objeto. Quando uma entrada de diário é navegada, seus Page metadados são usados para criar uma nova instância do Page. Como consequência, cada Page um que é navegado tem o tempo de vida que é ilustrado pela figura a seguir.

Page lifetime

Embora o uso do comportamento de registro no diário padrão possa economizar no consumo de memória, o desempenho de renderização por página pode ser reduzido; Reinstanciar um Page pode ser demorado, especialmente se tiver muito conteúdo. Se você precisar manter uma Page instância no diário, poderá usar duas técnicas para fazer isso. Primeiro, você pode navegar programaticamente até um Page objeto chamando o NavigationService.Navigate método.

Em segundo lugar, você pode especificar que o WPF retenha uma instância de a no diário definindo a PageKeepAlive propriedade como true (o padrão é false). Como mostrado no exemplo a seguir, você pode definir KeepAlive declarativamente na marcação.

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

A vida de um que é mantido vivo é sutilmente diferente de um Page que não é. A primeira vez que um que é mantido vivo é navegado, ele é instanciado como um PagePage que não é mantido vivo. No entanto, como uma instância do Page é retida no diário, ela nunca é instanciada novamente enquanto permanece no diário. Consequentemente, se um tem lógica de inicialização que precisa ser chamada toda vez que o é navegado, você deve movê-lo do construtor para um Page manipulador para o PageLoaded evento. Como mostrado na figura a seguir, os Loaded eventos e ainda são gerados cada vez que um Page é navegado de e Unloaded para, respectivamente.

When the Loaded and Unloaded events are raised

Quando um Page não é mantido vivo, você não deve fazer o seguinte:

  • Armazenar uma referência nela ou qualquer parte dela.

  • Registrar manipuladores de eventos com eventos que não são implementados por ela.

Fazer qualquer um desses criará referências que forçam a retenção na Page memória, mesmo depois de ter sido removido da revista.

Em geral, você deve preferir o comportamento padrão Page de não manter um Page vivo. No entanto, isso tem implicações de estado que são discutidas na próxima seção.

Reter o estado de conteúdo com o histórico de navegação

Se um não é mantido vivo, e ele tem controles que coletam dados do usuário, o que acontece com os dados se um Page usuário navega para fora e de volta para o Page? De uma perspectiva de experiência do usuário, o usuário deve ter a expectativa de ver os dados que inseriu anteriormente. Infelizmente, como uma nova instância do Page é criada com cada navegação, os controles que coletaram os dados são reinstanciados e os dados são perdidos.

Felizmente, o diário fornece suporte para lembrar dados em Page navegações, incluindo dados de controle. Especificamente, a entrada de diário para cada Page atua como um contêiner temporário para o estado associado Page . As etapas a seguir descrevem como esse suporte é usado quando um Page é navegado de:

  1. Uma entrada para a corrente Page é adicionada ao diário.

  2. O estado do é armazenado com a entrada de Page diário para essa página, que é adicionada à pilha traseira.

  3. O novo Page é navegado para.

Quando a página Page é navegada de volta para, usando o diário, as seguintes etapas ocorrem:

  1. O Page (a entrada de diário superior na pilha traseira) é instanciado.

  2. O Page é atualizado com o estado que foi armazenado com a entrada de diário para o Page.

  3. O Page é navegado de volta para.

WPF usa automaticamente esse suporte quando os seguintes controles são usados em um Page:

Se um Page usa esses controles, os dados inseridos neles são lembrados nas Page navegações, conforme demonstrado pela Cor FavoritaListBox na figura a seguir.

Page with controls that remember state

Quando um Page tem controles diferentes dos da lista anterior, ou quando o estado é armazenado em objetos personalizados, você precisa escrever código para fazer com que o diário lembre o estado nas Page navegações.

Se você precisar lembrar pequenos trechos de estado nas Page navegações, poderá usar propriedades de dependência (consulte DependencyProperty) configuradas com o FrameworkPropertyMetadata.Journal sinalizador de metadados.

Se o estado que você Page precisa lembrar nas navegações compreende várias partes de dados, talvez seja menos intensivo em código encapsular seu estado em uma única classe e implementar a IProvideCustomContentState interface.

Se você precisa navegar por vários estados de um único Page, sem navegar a Page partir do próprio, você pode usar IProvideCustomContentState e NavigationService.AddBackEntry.

Cookies

Outra maneira que os aplicativos WPF podem armazenar dados é com cookies, que são criados, atualizados e excluídos usando os SetCookie métodos e GetCookie . Os cookies que você pode criar no WPF são os mesmos cookies que outros tipos de aplicativos da Web usam; Cookies são partes arbitrárias de dados que são armazenados por um aplicativo em uma máquina cliente durante ou entre sessões do aplicativo. Os dados do cookie normalmente assumem a forma de um par nome/valor no formato a seguir.

Name=Value

Quando os dados são passados para o , juntamente com o Uri local para SetCookieo qual o cookie deve ser definido, um cookie é criado na memória e só está disponível durante a sessão do aplicativo atual. Esse tipo de cookie é conhecido como cookie de sessão.

Para armazenar um cookie entre sessões de aplicativo, uma data de validade deve ser adicionada ao cookie, usando o formato a seguir.

NOME=VALOR; expires=DAY, DD-MMM-YYYY HH:MM:SS GMT

Um cookie com uma data de expiração é armazenado na pasta Arquivos Temporários da Internet da instalação atual do Windows até que o cookie expire. Um cookie desse tipo é conhecido como um cookies persistente porque ele persiste entre as sessões de aplicativo.

Você recupera cookies de sessão e persistentes chamando o método, passando o Uri do local onde o cookie foi definido com o GetCookieSetCookie método.

A seguir estão algumas das maneiras pelas quais os cookies são suportados no WPF:

  • Aplicativos autônomos WPF e XBAPs podem criar e gerenciar cookies.

  • Os cookies criados por um XBAP podem ser acessados a partir do navegador.

  • XBAPs do mesmo domínio podem criar e compartilhar cookies.

  • XBAPs e páginas HTML do mesmo domínio podem criar e compartilhar cookies.

  • Os cookies são despachados quando XBAPs e páginas XAML soltas fazem solicitações da Web.

  • Tanto XBAPs de nível superior quanto XBAPs hospedados em IFRAMES podem acessar cookies.

  • O suporte a cookies no WPF é o mesmo para todos os navegadores suportados.

  • No Internet Explorer, a política P3P que diz respeito aos cookies é respeitada pelo WPF, particularmente no que diz respeito a XBAPs próprios e de terceiros.

Navegação estruturada

Se você precisar passar dados de um para outro, poderá passar os dados como argumentos para um Page construtor não sem parâmetros do Page. Observe que se você usar essa técnica, você deve manter o vivo, se não, na próxima vez que você navegar para o , WPF reinstancia o usando o PagePagePage construtor sem parâmetros.

Como alternativa, você Page pode implementar propriedades que são definidas com os dados que precisam ser passados. As coisas se tornam complicadas, no entanto, quando um Page precisa passar dados de volta para o Page que navegou até ele. O problema é que a navegação não suporta nativamente mecanismos para garantir que um Page será devolvido depois de navegado. Essencialmente, a navegação não dá suporte à semântica de chamada/retorno. Para resolver esse problema, o WPF fornece a PageFunction<T> classe que você pode usar para garantir que um Page seja retornado de forma previsível e estruturada. Para obter mais informações, consulte Visão geral de navegação estruturada.

A classe NavigationWindow

Neste ponto, você viu a gama de serviços de navegação que você provavelmente utilizará para criar aplicativos com conteúdo navegável. Esses serviços foram discutidos no contexto dos XBAPs, embora não se limitem aos XBAPs. Os sistemas operacionais modernos e os aplicativos do Windows aproveitam a experiência do navegador dos usuários modernos para incorporar a navegação no estilo do navegador em aplicativos autônomos. Exemplos comuns incluem:

  • Dicionário de sinônimos de palavras: navegue por opções de palavras.

  • Explorador de Arquivos: navegar por arquivos e pastas.

  • Assistentes: dividir uma tarefa complexa em várias páginas entre as quais se pode navegar. Um exemplo é o Assistente de componentes do Windows que lida com a adição e remoção de recursos do Windows.

Para incorporar a navegação no estilo do navegador em seus aplicativos autônomos, você pode usar a NavigationWindow classe. NavigationWindow deriva Window e estende-o com o mesmo suporte para navegação que os XBAPs fornecem. Você pode usar NavigationWindow como a janela principal do seu aplicativo autônomo ou como uma janela secundária, como uma caixa de diálogo.

Para implementar um NavigationWindow, como acontece com a maioria das classes de nível superior no WPF (Window, Pagee assim por diante), você usa uma combinação de marcação e code-behind. Isso é mostrado no exemplo a seguir.

<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

Esse código cria um que navega automaticamente para um NavigationWindowPage (HomePage.xaml) quando o NavigationWindow é aberto. Se o for a janela principal do aplicativo, você poderá usar o NavigationWindowStartupUri atributo para iniciá-lo. Isso é mostrado na marcação a seguir.

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

A figura a seguir mostra o como a NavigationWindow janela principal de um aplicativo autônomo.

A main window

Na figura, você pode ver que o NavigationWindow tem um título, mesmo que ele não tenha sido definido no NavigationWindow código de implementação do exemplo anterior. Em vez disso, o título é definido usando a propriedade, que é mostrada no código a WindowTitle seguir.

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

A definição das WindowWidth propriedades e WindowHeight também afeta o NavigationWindow.

Normalmente, você implementa o seu próprio NavigationWindow quando precisa personalizar seu comportamento ou sua aparência. Se nada disso é necessário, você pode usar um atalho. Se você especificar o URI do pacote de um como o em um aplicativo autônomo, criará automaticamente um PageNavigationWindow para hospedar o PageStartupUri . Application A marcação a seguir mostra como habilitar isso.

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

Se desejar que uma janela de aplicativo secundária, como uma caixa de diálogo, seja um NavigationWindow, você poderá usar o código no exemplo a seguir para abri-la.

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

A figura a seguir mostra o resultado.

A dialog box

Como você pode ver, NavigationWindow exibe os botões Voltar e Avançar no estilo do Internet Explorer que permitem que os usuários naveguem pelo diário. Esses botões fornecem a mesma experiência do usuário, conforme mostrado na figura a seguir.

Back and Forward buttons in a NavigationWindow

Se suas páginas fornecerem seu próprio suporte à navegação de diário e interface do usuário, você poderá ocultar os botões Voltar e Avançar exibidos NavigationWindow definindo o ShowsNavigationUI valor da propriedade como false.

Como alternativa, você pode usar o suporte de personalização no WPF para substituir a interface do usuário do NavigationWindow próprio.

A classe Frame

Tanto o navegador quanto NavigationWindow as janelas hospedam conteúdo navegável. Em alguns casos, os aplicativos têm conteúdo que não precisa ser hospedado por uma janela inteira. Em vez disso, esse tipo de conteúdo pode ser hospedado dentro de outro conteúdo. Você pode inserir conteúdo navegável em outro conteúdo usando a Frame classe. Frame fornece o mesmo suporte que NavigationWindow e XBAPs.

O exemplo a seguir mostra como adicionar um a um FramePage declarativamente usando o Frame elemento .

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

Essa marcação define o SourceFrame atributo do elemento com um URI de pacote para o qual o PageFrame deve navegar inicialmente. A figura a seguir mostra um XBAP com um que tem um PageFrame que navegou entre várias páginas.

A frame that has navigated between multiple pages

Você não precisa usar apenas dentro Frame do conteúdo de um Pagearquivo . Também é comum hospedar um dentro do conteúdo de um FrameWindowarquivo .

Por padrão, Frame só usa seu próprio diário na ausência de outro diário. Se um faz parte do conteúdo hospedado dentro de um FrameNavigationWindow ou um XBAP, Frame usa o diário que pertence ao NavigationWindow ou XBAP. Às vezes, porém, um Frame pode precisar ser responsável por sua própria revista. Uma razão para fazer isso é permitir a navegação do diário dentro das páginas hospedadas por um Framearquivo . Isso é ilustrado pela figura a seguir.

Frame and Page diagram

Nesse caso, você pode configurar o Frame para usar seu próprio diário definindo a JournalOwnershipFrame propriedade do para OwnsJournal. Isso é mostrado na marcação a seguir.

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

A figura a seguir ilustra o efeito de navegar dentro de um Frame diário que usa seu próprio diário.

A frame that uses its own journal

Observe que as entradas de diário são mostradas pela interface do usuário de navegação no Frame, e não pelo Internet Explorer.

Observação

Se um faz parte do conteúdo hospedado em um FrameWindow, usa seu próprio diário e, consequentemente, Frame exibe sua própria interface do usuário de navegação.

Se sua experiência de usuário exigir que um Frame forneça seu próprio diário sem mostrar a interface do usuário de navegação, você poderá ocultar a interface do usuário de navegação definindo o NavigationUIVisibility como Hidden. Isso é mostrado na marcação a seguir.

<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 e NavigationWindow são classes que são conhecidas como hosts de navegação. Um host de navegação é uma classe que pode navegar para o conteúdo e exibi-lo. Para fazer isso, cada host de navegação usa seu próprio NavigationService diário e diário. A construção básica de um host de navegação é mostrada na figura a seguir.

Navigator diagrams

Essencialmente, isso permite NavigationWindow e Frame fornece o mesmo suporte de navegação que um XBAP fornece quando hospedado no navegador.

Além de usar NavigationService um diário, os hosts de navegação implementam os mesmos membros que NavigationService implementam. Isso é ilustrado pela figura a seguir.

A journal in a Frame and in a NavigationWindow

Isso permite que você programe suporte a navegação diretamente em relação a eles. Você pode considerar isso se precisar fornecer uma interface do usuário de navegação personalizada para um que está hospedado em um FrameWindowarquivo . Além disso, ambos os tipos implementam membros adicionais relacionados à navegação, incluindo BackStack (, ) e (NavigationWindow.ForwardStackNavigationWindow.BackStack, ), que permitem enumerar as entradas de diário na pilha traseira e ForwardStack na pilha de encaminhamento, Frame.BackStackFrame.ForwardStackrespectivamente.

Conforme mencionado anteriormente, mais de um diário pode existir dentro de um aplicativo. A figura a seguir fornece um exemplo de quando isso pode acontecer.

Multiple journals within one application

Ao longo deste tópico, Page e pacote XBAPs foram usados para demonstrar os vários recursos de navegação do WPF. No entanto, um que é compilado em um Page aplicativo não é o único tipo de conteúdo que pode ser navegado, e pacotes XBAPs não são a única maneira de identificar conteúdo.

Como esta seção demonstra, você também pode navegar para arquivos XAML soltos, arquivos HTML e objetos.

Um arquivo XAML solto é um arquivo com as seguintes características:

  • Contém apenas XAML (ou seja, nenhum código).

  • Tem uma declaração de namespace apropriada.

  • Tem a extensão de nome de arquivo .xaml.

Por exemplo, considere o seguinte conteúdo armazenado como um arquivo XAML solto, 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>

Quando você clica duas vezes no arquivo, o navegador é aberto e então navega para o conteúdo e o exibe. Isso será mostrado na figura a seguir.

Display of the content in the Person.XAML file

Você pode exibir um arquivo XAML solto do seguinte:

  • Um site da Web no computador local, a intranet ou a Internet.

  • Um compartilhamento de arquivo UNC (Convenção Universal de Nomenclatura).

  • O disco local.

Um arquivo XAML solto pode ser adicionado aos favoritos do navegador ou ser a home page do navegador.

Observação

Para obter mais informações sobre como publicar e iniciar páginas XAML soltas, consulte Implantando um aplicativo WPF.

Uma limitação em relação ao XAML solto é que você só pode hospedar conteúdo seguro para ser executado em confiança parcial. Por exemplo, Window não pode ser o elemento raiz de um arquivo XAML solto. Para obter mais informações, consulte Segurança parcialmente confiável do WPF.

Como era de se esperar, você também pode navegar até HTML. Você simplesmente precisa fornecer um URI que usa o esquema http. Por exemplo, o XAML a seguir mostra um Frame que navega até uma página HTML.

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

Navegar para HTML requer permissões especiais. Por exemplo, você não pode navegar a partir de um XBAP que esteja sendo executado na área restrita de segurança de confiança parcial da zona da Internet. Para obter mais informações, consulte Segurança parcialmente confiável do WPF.

O WebBrowser controle suporta hospedagem de documentos HTML, navegação e interoperabilidade de script/código gerenciado. Para obter informações detalhadas sobre o WebBrowser controle, consulte WebBrowser.

Como Frame, navegar para HTML usando WebBrowser requer permissões especiais. Por exemplo, a partir de um aplicativo de confiança parcial, você pode navegar apenas para HTML localizado no site de origem. Para obter mais informações, consulte Segurança parcialmente confiável do WPF.

Se você tiver dados armazenados como objetos personalizados, uma maneira de exibir esses dados é criar um Page com conteúdo vinculado a esses objetos (consulte Visão geral da vinculação de dados). Se você não precisar da sobrecarga resultante da criação de uma página inteira apenas para exibir os objetos, você poderá navegar diretamente para eles em vez disso.

Considere a classe que é implementada no código a Person seguir.

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

Para navegar até ele, chame o NavigationWindow.Navigate método, conforme demonstrado pelo código a seguir.

<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

A figura a seguir mostra o resultado.

A page that navigates to a class

Nessa figura, você pode ver que nada útil é exibido. Na verdade, o valor exibido é o ToString valor de retorno do método para o objeto Person, por padrão, esse é o único valor que o WPF pode usar para representar seu objeto. Você pode substituir o ToString método para retornar informações mais significativas, embora ainda seja apenas um valor de cadeia de caracteres. Uma técnica que você pode usar que aproveita os recursos de apresentação do WPF é usar um modelo de dados. Você pode implementar um modelo de dados que o WPF pode associar a um objeto de um tipo específico. O código a seguir mostra um modelo de dados para o Person objeto.

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

Aqui, o modelo de dados é associado ao Person tipo usando a extensão de x:Type marcação no DataType atributo. Em seguida, o modelo de dados vincula TextBlock elementos (consulte TextBlock) às propriedades da Person classe. A figura a seguir mostra a aparência atualizada do Person objeto.

Navigating to a class that has a data template

Uma vantagem dessa técnica é a consistência você obtém sendo capaz de reutilizar o modelo de dados para exibir os objetos de forma consistente em qualquer lugar no aplicativo.

Para obter mais informações sobre modelos de dados, consulte Visão geral de modelagem de dados.

Segurança

O suporte à navegação WPF permite que XBAPs sejam navegados pela Internet e permite que os aplicativos hospedem conteúdo de terceiros. Para proteger aplicativos e usuários contra comportamentos nocivos, o WPF fornece uma variedade de recursos de segurança que são discutidos em Segurança e Segurança de Confiança Parcial do WPF.

Confira também