Compartilhar via


Visão Geral de Navegação Estruturada

Conteúdo que pode ser hospedado por um aplicativo de navegador XAML (XBAP), um Frame, ou um NavigationWindow é composto por páginas que podem ser identificadas por um pacote uniform resource identifiers (URIs) e navegado por hiperlinks. A estrutura das páginas e as maneiras como podem ser navegadas, como definido pelos hiperlinks, são conhecidas como topologia de navegação. Uma topologia como esta serve a uma variedade de tipos de aplicativos, particularmente aqueles que navegam através de documentos. Para tais aplicativos, o usuário pode navegar de uma página para outra sem as páginas precisarem saber nada sobre a outra.

Entretanto, outros tipos de aplicativos possuem páginas que precisam saber quando foram navegadas. Por exemplo, considere um aplicativo de recursos humanos que possui uma página para listas todos os empregados de uma organização — a página "Lista de Empregados". Esta página poderia permitir aos usuários adicionar um novo empregado clicando-se em um hiperlink. Quando clicada, a página navega para uma página "Adicione um Empregado" para obter os detalhes do novo empregado e retorná-los à página "Lista de Empregados" para criar o novo empregado e atualizar a lista. Este estilo de navegação é similar a chamar um método para fazer algum processamento e retornar um valor, o que é conhecido como programação estruturada. Assim, este estilo de navegação é conhecido como navegação estruturada.

A classe Page não implementa suporta à navegação estruturada. Ao invés disso, a classe PageFunction<T> deriva de Page e a estende com as construções básicas necessárias para navegação estruturada. Este tópico mostra como estabelecer navegação estruturada usando PageFunction<T>.

ObservaçãoObservação:

É proveniente de exemplo integrado esta visão geral do Exemplo de navegação estruturado.

Este tópico contém as seguintes seções.

  • Navegação Estruturada
  • Navegação Estruturada com PageFunction
  • Outros Tipos de Navegação Estruturada
  • Tópicos relacionados

Quando uma página chama outra página em uma navegação estruturada, alguns ou todos os seguintes comportamentos são necessários:

  • A página chamadora navega para a página chamada, opcionalmente passando parâmetros exigidos pela página chamada.

  • A página chamada, quando o usuário tiver terminado de usar a página chamadora, retorna especificamente para a página chamadora, opcionalmente:

    • Retornando informações de estado que descrevem como a página chamadora completou (por exemplo, se o usuário pressionou um botão OK ou Cancelar).

    • Retornando os dados que foram coletados do usuário (por exemplo, detalhes do novo empregador).

  • Quando a página chamadora retorna para a página chamada, a página chamada é removida do histórico de navegação para isolar uma instância da página chamada da outra.

Estes comportamentos são ilustrados pela figura a seguir.

Fluxo entre a página chamadora e a página chamada

Você pode implementar estes comportamentos usando uma PageFunction<T> como a página chamada.

Este tópico mostra como implementar a mecânica básica da navegação estruturada envolvendo um único PageFunction<T>. Neste exemplo, uma Page chama uma PageFunction<T> para obter um valor String do usuário e retorná-lo.

Criando uma Página Chamadora

A página que chama a PageFunction<T> pode ser tanto uma Page como uma PageFunction<T>. Neste exemplo, ele é uma Page, como exibido no código a seguir.

<Page 
    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="StructuredNavigationSample.CallingPage"
    WindowTitle="Calling Page" 
    WindowWidth="250" WindowHeight="150">


...


</Page>
Imports System.Windows ' RoutedEventArgs, RoutedEventHandler, Visibility
Imports System.Windows.Controls ' Page
Imports System.Windows.Navigation ' ReturnEventArgs

Namespace StructuredNavigationSample

Public Class CallingPage
    Inherits Page
    Public Sub New()
        Me.InitializeComponent()


...


End Sub


...


End Class

End Namespace
using System.Windows; // RoutedEventArgs, RoutedEventHandler, Visibility
using System.Windows.Controls; // Page
using System.Windows.Navigation; // ReturnEventArgs

namespace StructuredNavigationSample
{
    public partial class CallingPage : Page
    {
        public CallingPage()
        {
            InitializeComponent();


...


}


...


    }
}

Criando uma Chamada Page Function

Porque a página chamadora pode usar a página chamada para coletar e retornar dados do usuário, PageFunction<T> é implementado como uma classe genérica cujo tipo de argumento especifica o tipo de valor que a página chamada irá retornar. O código a seguir mostra a implementação inicial da página chamada, usando um PageFunction<T>, que retorna um String.

<PageFunction
    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:sys="clr-namespace:System;assembly=mscorlib" 
    x:Class="StructuredNavigationSample.CalledPageFunction"
    x:TypeArguments="sys:String"
    Title="Page Function" 
    WindowWidth="250" WindowHeight="150">

  <Grid Margin="10">

    <Grid.ColumnDefinitions>
      <ColumnDefinition Width="Auto" />
      <ColumnDefinition />
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
      <RowDefinition Height="Auto" />
      <RowDefinition />
    </Grid.RowDefinitions>

    <!-- Data -->
    <Label Grid.Column="0" Grid.Row="0">DataItem1:</Label>
    <TextBox Grid.Column="1" Grid.Row="0" Name="dataItem1TextBox"></TextBox>

    <!-- Accept/Cancel buttons -->
    <TextBlock Grid.Column="1" Grid.Row="1" HorizontalAlignment="Right">
      <Button Name="okButton" IsDefault="True" MinWidth="50">OK</Button>
      <Button Name="cancelButton" IsCancel="True" MinWidth="50">Cancel</Button>
    </TextBlock>

  </Grid>

</PageFunction>
Imports System ' String
Imports System.Windows ' RoutedEventArgs, RoutedEventHandler
Imports System.Windows.Navigation ' PageFunction

Namespace StructuredNavigationSample

Public Class CalledPageFunction
    Inherits PageFunction(Of String)
    Public Sub New()
        Me.InitializeComponent()
    End Sub


...


End Class

End Namespace
using System; // String
using System.Windows; // RoutedEventArgs, RoutedEventHandler
using System.Windows.Navigation; // PageFunction

namespace StructuredNavigationSample
{
    public partial class CalledPageFunction : PageFunction<String>
    {
        public CalledPageFunction()
        {
            InitializeComponent();
        }


...


    }
}

A declaração de um PageFunction<T> é similar à declaração de uma Page com a adição dos argumentos de tipo. Como você pode ver do código de exemplo, os argumentos de tipo são especificados tanto em marcação XAML, usando o atributo x:TypeArguments, como code-behind, usando sintaxe padrão de tipos genéricos de argumentos.

Você não precisa usar apenas classes .NET Framework como argumentos de tipo. Um PageFunction<T> poderia ser chamado para obter dados específicos do domínio abstraídos como um tipo customizado. O código a seguir mostra como usar um tipo customizado como um argumento de tipo para um PageFunction<T>.

Os argumentos de tipo para o PageFunction<T> fornecem a fundação para a comunicação entre a página chamadora e a página chamada, que são discutidos nas seções seguintes.

Como será visto, o tipo identificado com a declaração de um PageFunction<T> tem um papel importante no retorno de dados de um PageFunction<T> para uma página chamadora.

Chamando uma PageFunction e Passando Parâmetros

Para chamar uma página, a página chamadora precisa instanciar a página chamada e navegar para ele usando o método Navigate. Isto permite à página chamadora passar dados iniciais para a página chamada, como valores padrão para os dados sendo obtidos pela página chamada.

O código a seguir mostra a página chamadora com um construtor não padrão para aceitar parâmetros da página chamadora.

Imports System ' String
Imports System.Windows ' RoutedEventArgs, RoutedEventHandler
Imports System.Windows.Navigation ' PageFunction

Namespace StructuredNavigationSample

Public Class CalledPageFunction
    Inherits PageFunction(Of String)


...


Public Sub New(ByVal initialDataItem1Value As String)
    Me.InitializeComponent()


...


    ' Set initial value
    Me.dataItem1TextBox.Text = initialDataItem1Value
End Sub


...


End Class

End Namespace
using System; // String
using System.Windows; // RoutedEventArgs, RoutedEventHandler
using System.Windows.Navigation; // PageFunction

namespace StructuredNavigationSample
{
    public partial class CalledPageFunction : PageFunction<String>
    {


...


public CalledPageFunction(string initialDataItem1Value)
{
    InitializeComponent();



...


    // Set initial value
    this.dataItem1TextBox.Text = initialDataItem1Value;
}

O código a seguir mostra a página chamadora tratando o evento Click do Hyperlink declarado anteriormente para instanciar a página chamada e passar para ela um valor de string inicial.

Imports System ' String
Imports System.Windows ' RoutedEventArgs, RoutedEventHandler
Imports System.Windows.Navigation ' PageFunction

Namespace StructuredNavigationSample

Public Class CalledPageFunction
    Inherits PageFunction(Of String)


...


Public Sub New(ByVal initialDataItem1Value As String)
    Me.InitializeComponent()


...


    ' Set initial value
    Me.dataItem1TextBox.Text = initialDataItem1Value
End Sub


...


End Class

End Namespace
using System; // String
using System.Windows; // RoutedEventArgs, RoutedEventHandler
using System.Windows.Navigation; // PageFunction

namespace StructuredNavigationSample
{
    public partial class CalledPageFunction : PageFunction<String>
    {


...


public CalledPageFunction(string initialDataItem1Value)
{
    InitializeComponent();



...


    // Set initial value
    this.dataItem1TextBox.Text = initialDataItem1Value;
}

Não é necessário passar parâmetros para a página chamada. Ao invés disso, você poderia fazer o seguinte:

Mas, como será visto brevemente, você ainda precisará usar código para instanciar e navegar para a página chamada para coletar os dados retornados pela página chamada. Por esta razão, o PageFunction<T> precisa ser mantido vivo; de outra forma, a próxima vez que você navegar para o PageFunction<T>, WPF instancia o PageFunction<T> usando o construtor padrão.

Antes da página chamada poder retornar, entretanto, ela precisa retornar os dados que podem ser recuperados pela página chamadora.

Retornando Resultados de Tarefa e Dados de Tarefa a partir de uma Tarefa para uma Página Chamadora

Assim que o usuário tiver terminado de usar a página chamada, como neste exemplo pressionando o botão OK ou Cancelar, a página chamada precisa retornar. Como a página chamadora usou a página chamada para coletar dados do usuário, a página chamadora necessita de dois tipos de informação:

  1. Se o usuário cancelou a página chamada (pressionando ou o botão OK ou o botão Cancelar neste exemplo). Isto permite à página chamadora determinar se processa os dados que a página chamadora obteve do usuário.

  2. Os dados que foram fornecidos pelo usuário.

Para retornar informação, PageFunction<T> implementa o método OnReturn. O código a seguir mostra como chamá-lo.

Imports System ' String
Imports System.Windows ' RoutedEventArgs, RoutedEventHandler
Imports System.Windows.Navigation ' PageFunction

Namespace StructuredNavigationSample

Public Class CalledPageFunction
    Inherits PageFunction(Of String)


...


    Private Sub okButton_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
        ' Accept when Ok button is clicked
        Me.OnReturn(New ReturnEventArgs(Of String)(Me.dataItem1TextBox.Text))
    End Sub

    Private Sub cancelButton_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
        ' Cancel
        Me.OnReturn(Nothing)
    End Sub
End Class

End Namespace
using System; // String
using System.Windows; // RoutedEventArgs, RoutedEventHandler
using System.Windows.Navigation; // PageFunction

namespace StructuredNavigationSample
{
    public partial class CalledPageFunction : PageFunction<String>
    {


...


        void okButton_Click(object sender, RoutedEventArgs e)
        {
            // Accept when Ok button is clicked
            OnReturn(new ReturnEventArgs<string>(this.dataItem1TextBox.Text));
        }

        void cancelButton_Click(object sender, RoutedEventArgs e)
        {
            // Cancel 
            OnReturn(null);
        }
    }
}

Neste exemplo, se um usuário pressiona o botão Cancelar, o valor de null é retornado para a página chamadora. Se o botão OK for pressionado em vez disso, será retornado o valor de seqüência de caracteres fornecido pelo usuário. OnReturn is a protected virtual method that you call to return your data to the calling page. Seus dados precisam ser empacotados em uma instância do tipo genérico ReturnEventArgs<T>, cujo argumento de tipo especifica o tipo de valor que Result retorna. Dessa forma, quando você declara um PageFunction<T> com um argumento de tipo particular, você está dizendo que um PageFunction<T> vai retornar uma instância do tipo que está especificado como argumento de tipo. Neste exemplo, o argumento de tipo, e, consequentemente, o valor de retorno são do tipo String.

Quando OnReturn é chamado, a página chamadora precisa de uma forma de receber o valor de retorno do PageFunction<T>. Por este motivo, PageFunction<T> implementa o evento Return para as páginas chamadoras tratarem. Quando OnReturn é chamado, Return é disparado, de forma que a página chamadora pode registrar com Return para receber a notificação.

Imports System.Windows ' RoutedEventArgs, RoutedEventHandler, Visibility
Imports System.Windows.Controls ' Page
Imports System.Windows.Navigation ' ReturnEventArgs

Namespace StructuredNavigationSample

Public Class CallingPage
    Inherits Page


...


    Private Sub pageFunctionHyperlink_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
        ' Instantiate and navigate to page function
        Dim calledPageFunction As New CalledPageFunction("Initial Data Item Value")
        AddHandler calledPageFunction.Return, New ReturnEventHandler(Of String)(AddressOf Me.calledPageFunction_Return)
        MyBase.NavigationService.Navigate(calledPageFunction)
    End Sub
    Private Sub calledPageFunction_Return(ByVal sender As Object, ByVal e As ReturnEventArgs(Of String))

        Me.pageFunctionResultsTextBlock.Visibility = Windows.Visibility.Visible

        ' Display result
        Me.pageFunctionResultsTextBlock.Text = IIf((Not e Is Nothing), "Accepted", "Canceled")

        ' If page function returned, display result and data
        If (Not e Is Nothing) Then
            Me.pageFunctionResultsTextBlock.Text = (Me.pageFunctionResultsTextBlock.Text & ChrW(10) & e.Result)
        End If

    End Sub
End Class

End Namespace
using System.Windows; // RoutedEventArgs, RoutedEventHandler, Visibility
using System.Windows.Controls; // Page
using System.Windows.Navigation; // ReturnEventArgs

namespace StructuredNavigationSample
{
    public partial class CallingPage : Page
    {


...


        void pageFunctionHyperlink_Click(object sender, RoutedEventArgs e)
        {
            // Instantiate and navigate to page function
            CalledPageFunction CalledPageFunction = new CalledPageFunction("Initial Data Item Value");
            CalledPageFunction.Return += pageFunction_Return;
            this.NavigationService.Navigate(CalledPageFunction);
        }
        void pageFunction_Return(object sender, ReturnEventArgs<string> e)
        {
            this.pageFunctionResultsTextBlock.Visibility = Visibility.Visible;

            // Display result
            this.pageFunctionResultsTextBlock.Text = (e != null ? "Accepted" : "Canceled");

            // If page function returned, display result and data
            if (e != null)
            {
                this.pageFunctionResultsTextBlock.Text += "\n" + e.Result;
            }
        }
    }
}

Removendo Páginas de Tarefa Quando a Tarefa Termina

Quando uma página chamada retorna, e o usuário não cancelou a página, a página chamadora irá processar os dados que foram fornecidos pelo usuário e também retornados pela página chamada. Aquisição de dados desta forma são uma atividade isolada; quando a página chamada retorna, a página chamadora precisa criar e navegar para uma nova página chamadora para capturar mais dados.

Entretanto, a não ser que uma página chamada seja removida do the journal, um usuário poderá navegar de volta para uma instância anterior da página chamadora. Se um PageFunction<T> será retido no the journal é determinado pela propriedade RemoveFromJournal. Por padrão, uma page function é automaticamente removida quando OnReturn é chamada porque RemoveFromJournal é definida como true. Para manter uma page function no histórico de navegação depois que OnReturn é chamado, defina RemoveFromJournal como false.

Outros Tipos de Navegação Estruturada

Este tópico ilustra o uso mais básico de um PageFunction<T> para dar suporte à navegação estruturada chamada/retorno. Esta base fornece a capacidade de criar tipos mais complexos de navegação estruturada.

Por exemplo, algumas vezes múltiplas páginas são necessárias pela página chamadora para obter dados suficientes do usuário ou para realizar uma tarefa. O uso de múltiplas página é chamado de um "assistente". Para obter mais informações sobre assistentes, consulte Exemplo de Assistente.

Em outros casos, aplicativos podem possuem topologias de navegação mais complexas que dependem de navegação estruturada para operar eficientemente. Para obter mais informações, consulte Visão geral sobre topologias de navegação.

Consulte também

Tarefas

Exemplo de navegação estruturado

Conceitos

Visão geral sobre topologias de navegação

Referência

PageFunction<T>

NavigationService