Partilhar via


Visão geral de navegação

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

Page, Hyperlink, NavigationServicee o diário formam o núcleo do suporte à 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 incluem 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 é referenciada.

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 dos 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 .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 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 elemento raiz e requer a declaração de namespace XML do WPF. O Page elemento contém o conteúdo para o qual 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 Page elemento são considerados o conteúdo de um Page 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.

Um somente Page marcação é útil para exibir conteúdo. No entanto, a 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 x:Class build da Microsoft (MSBuild) crie uma partial classe que deriva e Page 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 é chamada para registrar os eventos e definir as propriedades 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 a marcação e o 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 arquivo de início Page.

Configurar uma página inicial

Os XBAPs exigem que uma certa quantidade de infraestrutura de aplicativos seja hospedada em um navegador. No WPF, a Application classe faz parte de uma definição de aplicativo que estabelece a 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 . Veja a seguir 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 é carregado Page automaticamente quando o XBAP é iniciado. Você faz isso definindo a StartupUri propriedade com o URI (Uniform Resource Identifier, identificador uniforme de recurso) para o Page.

Observação

Na maioria dos casos, o é compilado ou implantado Page com um aplicativo. Nesses casos, o URI que identifica a Page é um URI de pacote, que é um URI que está em conformidade com o esquema de pacotes . Os URIs de pacote são discutidos mais detalhadamente 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.

Página XBAP

Observação

Para obter mais informações sobre o desenvolvimento e a implantação de XBAPs, consulte Visão geral dos 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 do XBAP. Além de ser longo, o título não é atraente nem informativo. Por esse motivo, Page oferece uma maneira de alterar o título definindo a WindowTitle propriedade. Além disso, você pode configurar a largura e a altura da janela do navegador definindo WindowWidth e WindowHeight, respectivamente.

WindowTitle, WindowWidthe WindowHeight pode ser definido declarativamente na marcação, 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"
    WindowTitle="Page Title"
    WindowWidth="500"
    WindowHeight="200">
  Hello, from the XBAP HomePage!
</Page>

O resultado é mostrado na figura a seguir.

Título da janela, altura, largura

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 a Hyperlink a a Page usando o Hyperlink elemento, que é mostrado na marcação a 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 Page pacote para 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 Page que tem um Hyperlink.

Página com hiperlink

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 à lista Páginas Recentes no Internet Explorer. Isso será mostrado na figura a seguir.

Botões Voltar e Avançar

Além de oferecer suporte à navegação de um Page para outro, Hyperlink também oferece suporte à navegação de fragmentos.

Navegação de fragmento

A navegação de fragmento é a navegação para um fragmento de conteúdo no arquivo .Page 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 conjunto de atributos. 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>

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

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

  • Um caractere "#".

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

Um URI de fragmento tem o seguinte formato.

PageURI # ElementName

Veja a seguir um exemplo de um Hyperlink que está configurado para navegar até um 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 para seus próprios fragmentos.

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

Quando a é clicado, o Hyperlink WPF chama NavigationService.Navigate para localizar e baixar o Page URI do pacote especificado. O baixado Page é convertido em uma árvore de objetos cujo objeto raiz é uma instância do arquivo Page. Uma referência ao objeto raiz Page é armazenada NavigationService.Content na propriedade. O URI do pacote para o conteúdo para o qual foi navegado é armazenado na NavigationService.Source propriedade, enquanto armazena NavigationService.CurrentSource o 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 a Hyperlink seja um host de navegação (consulte Hosts de navegação), Hyperlink será capaz de 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 Page usando um construtor sem parâmetros.

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

  • Quando o Page que precisa ser navegado 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 Navigate método do NavigationService objeto. Isso requer obter uma referência a um NavigationService.

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 NavigationService que navegou até o .Page Você pode obter uma referência a um NavigationService chamando o staticNavigationService.GetNavigationService método. Para obter o NavigationService que navegou para um determinado Page, você passa uma referência para o Page como o argumento do GetNavigationService método. O código a seguir mostra como obter o NavigationService para o 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 os NavigationService fóruns Page, 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 ao seu NavigationService quando Page gera 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 Page. A navegação programática é necessária porque o Page que está sendo navegado só pode ser instanciado usando um único construtor sem parâmetros. O Page com o construtor sem parâmetros é 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 Page com o construtor sem parâmetros é mostrado na marcação e no 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 Hyperlink on this Page é clicado, a navegação é iniciada instanciando o Page para navegar usando o construtor sem parâmetros e chamando o NavigationService.Navigate método. Navigate aceita uma referência ao objeto para o qual navegará NavigationService , 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), poderá 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

A 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 rastrear e influenciar a navegação usando os seguintes eventos 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.

Gráfico de fluxo de navegação de página

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

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

Em alguns casos, a Page pode estar interessado nesses eventos. Por exemplo, a Page pode manipular o evento para determinar se deve ou não cancelar a NavigationService.Navigating navegação para 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 o exemplo anterior faz, você também deve cancelar o registro do manipulador de eventos. Caso contrário, pode haver efeitos colaterais em relação à forma 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 de retorno e uma pilha de avanço. Quando você navega do atual Page para um novo Page ou encaminha para um existente Page, o atual Page é adicionado à pilha de retorno. Quando você navega da corrente Page de volta para a anterior Page, a corrente Page é 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 de retorno e na pilha de encaminhamento é uma instância da JournalEntry classe e é chamado de entrada de diário.

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

Botões Voltar e Avançar

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 pelas páginas em um XBAP usando os botões Voltar, Avançar 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 do Page. 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 valor do Page.Title atributo.

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

  4. O URI para o domínio .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 Page.Title atributo para alterar o 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. Um motivo para fazer isso é fornecer interfaces de navegação personalizadas em suas páginas.

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

<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 avançado, 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" as páginas que foram navegadas, esse XBAP pode consumir rapidamente uma quantidade grande e perceptível 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 arquivo .Page Como consequência, cada Page um que é navegado tem o tempo de vida ilustrado pela figura a seguir.

Tempo de vida da página

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, principalmente se tiver muito conteúdo. Se você precisar manter uma Page instância no diário, poderá recorrer a duas técnicas para fazer isso. Primeiro, você pode navegar programaticamente para um Page objeto chamando o NavigationService.Navigate método.

Em segundo lugar, você pode especificar que o WPF retenha uma instância de a Page no diário definindo a KeepAlive propriedade como true (o padrão é false). Conforme 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>

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

Quando os eventos Loaded e Unloaded são gerados

Quando a 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 uma dessas ações criará referências que forçam a retenção na Page memória, mesmo depois de ter sido removida do diário.

Em geral, você deve preferir o comportamento padrão Page de não manter um Page ativo. 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 a Page não for mantido ativo e tiver controles que coletam dados do usuário, o que acontecerá com os dados se um usuário navegar 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 a 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 um atua como um contêiner temporário para o estado associado Page . As etapas a seguir descrevem como esse suporte é usado quando a Page é navegado:

  1. Uma entrada para o atual Page é adicionada ao diário.

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

  3. O novo Page é navegado para.

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

  1. A Page (a entrada de diário superior na pilha de retorno) é instanciada.

  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.

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

Se a Page usar esses controles, os dados inseridos neles serão lembrados nas Page navegações, conforme demonstrado pela CorListBox Favorita na figura a seguir.

Página com controles que lembram o estado

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

Se você precisar se lembrar de pequenos pedaços 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 incluir vários dados, você poderá achar menos intensivo em código encapsular seu estado em uma única classe e implementar a IProvideCustomContentState interface.

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

Cookies

Outra maneira pela qual 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 Web usam; Cookies são partes arbitrárias de dados que são armazenadas por um aplicativo em uma máquina cliente durante ou entre sessões de aplicativo. Os dados do cookie normalmente assumem a forma de um par nome/valor no formato a seguir.

Valor do nome =

Quando os dados são passados para SetCookie, juntamente com o Uri local para o qual o cookie deve ser definido, um cookie é criado na memória e fica disponível apenas 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 GetCookie método, passando o Uri do local onde o cookie foi definido com o SetCookie método.

Veja a seguir algumas das maneiras pelas quais os cookies são suportados no WPF:

  • Aplicativos autônomos do 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 enviados quando XBAPs e páginas XAML soltas fazem solicitações da Web.

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

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

  • No Internet Explorer, a política P3P que pertence a cookies é respeitada pelo WPF, especialmente no que diz respeito a XBAPs primários e de terceiros.

Navegação estruturada

Se você precisar passar dados de um Page para outro, poderá passar os dados como argumentos para um construtor sem parâmetros do Page. Observe que, se você usar essa técnica, deverá manter o Page ativo; caso contrário, na próxima vez que navegar até o , o PageWPF reinstanciará o Page usando o construtor sem parâmetros.

Como alternativa, você Page pode implementar propriedades definidas com os dados que precisam ser passados. As coisas ficam complicadas, no entanto, quando a Page precisa passar dados de volta para o Page que navegou até ele. O problema é que a navegação não oferece suporte nativo a mecanismos para garantir que a Page será retornado depois de navegar. 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 a Page seja retornado de maneira 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 de 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 e Window o estende com o mesmo suporte para navegação que os XBAPs fornecem. Você pode usar NavigationWindow como a janela principal do aplicativo autônomo ou como uma janela secundária, como uma caixa de diálogo.

Para implementar um , como acontece com a NavigationWindowmaioria das classes de nível superior no WPF (Window, Page, e 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 NavigationWindow que navega automaticamente para um Page (HomePage.xaml) quando o NavigationWindow é aberto. Se for NavigationWindow a janela principal do aplicativo, você poderá usar o StartupUri atributo para iniciá-la. 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 NavigationWindow como a janela principal de um aplicativo autônomo.

Uma janela principal

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 WindowTitle no código a seguir.

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

Definir as 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 a como o StartupUri em um aplicativo autônomo, Application o criará automaticamente um NavigationWindow para hospedar o Page.Page A marcação a seguir mostra como habilitar isso.

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

Se você quiser que uma janela secundária do aplicativo, como uma caixa de diálogo, seja um NavigationWindow, você pode 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.

Uma caixa de diálogo

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

Botões Voltar e Avançar em um 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 valor da ShowsNavigationUI propriedade como false.

Como alternativa, você pode usar o suporte à 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 que 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 os XBAPs.

O exemplo a seguir mostra como adicionar a Frame a a declarativamente Page 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 Source Frame atributo do elemento com um URI de pacote para o Page qual o Frame deve navegar inicialmente. A figura a seguir mostra um XBAP com um Page que tem um Frame que navegou entre várias páginas.

Um quadro que navegou entre várias páginas

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

Por padrão, Frame o usa apenas seu próprio diário na ausência de outro diário. Se a Frame fizer parte do conteúdo hospedado em um NavigationWindow ou em um XBAP, Frame usará o diário que pertence ao NavigationWindow ou XBAP. Às vezes, porém, um Frame pode precisar ser responsável por seu próprio diário. Um motivo para fazer isso é permitir a navegação no diário nas páginas hospedadas por um Frame. Isso é ilustrado pela figura a seguir.

Diagrama de quadro e página

Nesse caso, você pode configurar o Frame para usar seu próprio diário definindo a JournalOwnership propriedade do Frame método 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 que usa seu próprio diário.

Um quadro que usa seu próprio diário

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 a Frame fizer parte do conteúdo hospedado em um Window, Frame o usará seu próprio diário e, consequentemente, exibirá sua própria interface do usuário de navegação.

Se a experiência do usuário exigir que a 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 .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 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.

Diagramas do navegador

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.

Um diário em um Frame e em um 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 Frame host .Window Além disso, ambos os tipos implementam membros adicionais relacionados à navegação, incluindo BackStack (NavigationWindow.BackStack, Frame.BackStack) e ForwardStack (NavigationWindow.ForwardStack, Frame.ForwardStack), que permitem enumerar as entradas de diário na pilha de retorno e na pilha de encaminhamento, respectivamente.

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.

Vários diários em um aplicativo

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

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

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 conteúdo a seguir 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.

Exibição do conteúdo no arquivo Person.XAML

Você pode exibir um arquivo XAML solto do seguinte:

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

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

  • 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 execução 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 você pode esperar, você também pode navegar até HTML. Você só precisa fornecer um URI que use o esquema http. Por exemplo, o XAML a seguir mostra um Frame que navega para 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 de um XBAP que está 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 dá suporte à 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, em 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 associado 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 implementada Person no código a 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.

Uma página que navega para uma classe

Nessa figura, você pode ver que nada útil é exibido. Na verdade, o valor exibido é o valor retornado do ToString 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 DataType extensão de x:Type marcação no atributo. Em seguida, o modelo de dados associa TextBlock elementos (consulte TextBlock) às propriedades da Person classe. A figura a seguir mostra a aparência atualizada do Person objeto.

Navegando para uma classe que tem um modelo de dados

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 do WPF permite que os XBAPs sejam navegados pela Internet e permite que os aplicativos hospedem conteúdo de terceiros. Para proteger aplicativos e usuários contra comportamento prejudicial, 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