Visão geral da navegação estruturada

O conteúdo que pode ser hospedado por um aplicativo de navegador XAML (XBAP), um , ou um FrameNavigationWindow é composto de páginas que podem ser identificadas por URIs (Uniform Resource Identifiers, identificadores uniformes de recursos) do pacote e navegadas por hiperlinks. A estrutura de páginas e as maneiras pelas quais elas podem ser navegadas, como definidas pelos hiperlinks, é conhecida como uma topologia de navegação. Uma topologia como esta serve a uma variedade de tipos de aplicativos, especialmente aqueles que navegam através de documentos. Para tais aplicativos, o usuário pode navegar de uma página à outra sem que as páginas precisem saber qualquer coisa sobre a outra.

No entanto, outros tipos de aplicativos têm páginas que precisam saber quando houve navegação entre elas. Por exemplo, considere um aplicativo de recursos humanos que tem uma página para listar todos os funcionários de uma organização, a página "Lista de funcionários". Esta página também pode permitir que os usuários adicionem um novo funcionário, clicando em um hiperlink. Ao clicar, a página navega para uma página "Adicionar um funcionário" para obter detalhes do novo empregado e retorná-los para a página "Lista de funcionários" para criar o novo funcionário e atualizar a lista. Este estilo de navegação é semelhante a chamar um método para fazer algum processamento e retornar um valor, que é conhecido como programação estruturada. Assim, este estilo de navegação é conhecido como navegação estruturada.

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

Navegação estruturada

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 até a página chamada, opcionalmente passando parâmetros exigidos pela página chamada.

  • Quando um usuário tiver terminado de usar a página chamadora, a página chamada retorna especificamente para a página chamadora, de forma opcional:

    • Informações de estado de retorno que descrevem como a página chamadora foi concluída (por exemplo, se o usuário pressionou um botão OK ou um botão Cancelar).

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

  • Quando a página chamadora retorna para a página chamada, a página chamada é removida do histórico de navegação para isolar instâncias de páginas chamadas.

Esses comportamentos são ilustrados pela figura a seguir:

Screenshot shows the flow between calling page and called page.

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

Navegação estruturada com PageFunction

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

Criando uma página chamadora

A página que chama um pode ser um ou um PageFunction<T>PagePageFunction<T>arquivo . Neste exemplo, é um Page, conforme mostrado 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="StructuredNavigationSample.CallingPage"
    WindowTitle="Calling Page" 
    WindowWidth="250" WindowHeight="150">
</Page>
using System.Windows;
using System.Windows.Controls;
using System.Windows.Navigation;

namespace StructuredNavigationSample
{
    public partial class CallingPage : Page
    {
        public CallingPage()
        {
            InitializeComponent();
Imports System.Windows
Imports System.Windows.Controls
Imports System.Windows.Navigation

Namespace StructuredNavigationSample

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

End Namespace

Criando uma função de página para chamar

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

<PageFunction
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://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>
using System;
using System.Windows;
using System.Windows.Navigation;

namespace StructuredNavigationSample
{
    public partial class CalledPageFunction : PageFunction<String>
    {
        public CalledPageFunction()
        {
            InitializeComponent();
        }
Imports System.Windows
Imports System.Windows.Navigation

Namespace StructuredNavigationSample

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

End Namespace

A declaração de a é semelhante à declaração de a com a PageFunction<T>Page adição dos argumentos de tipo. Como você pode ver no exemplo de código, os argumentos de tipo são especificados na marcação XAML, usando o atributo e code-behind, usando a x:TypeArguments sintaxe de argumento de tipo genérico padrão.

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

namespace SDKSample
{
    public class CustomType
    {
Public Class CustomType
    }
}
End Class
<PageFunction
    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.CustomTypePageFunction"
    x:TypeArguments="local:CustomType">
</PageFunction>
using System.Windows.Navigation;

namespace SDKSample
{
    public partial class CustomTypePageFunction : PageFunction<CustomType>
    {
Partial Public Class CustomTypePageFunction
    Inherits System.Windows.Navigation.PageFunction(Of CustomType)
    }
}
End Class

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

Como você verá, o tipo identificado com a declaração de a desempenha um papel importante no retorno de dados de a para a PageFunction<T>PageFunction<T> página de chamada.

Chamando uma PageFunction e passando parâmetros

Para chamar uma página, a página de chamada deve instanciar a página chamada e navegar até ela usando o Navigate método. Isso permite que a página chamadora passe dados iniciais para a página chamada, como valores padrão para os dados que estão sendo coletados pela página chamada.

O código a seguir mostra a página chamada com um construtor sem parâmetros para aceitar parâmetros da página de chamada.

using System;
using System.Windows;
using System.Windows.Navigation;

namespace StructuredNavigationSample
{
    public partial class CalledPageFunction : PageFunction<String>
    {
Imports System.Windows
Imports System.Windows.Navigation

Namespace StructuredNavigationSample

Public Class CalledPageFunction
    Inherits PageFunction(Of String)
public CalledPageFunction(string initialDataItem1Value)
{
    InitializeComponent();

Public Sub New(ByVal initialDataItem1Value As String)
    Me.InitializeComponent()
    // Set initial value
    this.dataItem1TextBox.Text = initialDataItem1Value;
}
    ' Set initial value
    Me.dataItem1TextBox.Text = initialDataItem1Value
End Sub
    }
}
End Class

End Namespace

O código a seguir mostra a página de chamada manipulando o Click evento do para instanciar a página chamada e passar a ela um valor de cadeia de Hyperlink caracteres inicial.

<Hyperlink Name="pageFunctionHyperlink">Call Page Function</Hyperlink>
using System.Windows;
using System.Windows.Controls;
using System.Windows.Navigation;

namespace StructuredNavigationSample
{
    public partial class CallingPage : Page
    {
        public CallingPage()
        {
            InitializeComponent();
            this.pageFunctionHyperlink.Click += new RoutedEventHandler(pageFunctionHyperlink_Click);
        }
        void pageFunctionHyperlink_Click(object sender, RoutedEventArgs e)
        {

            // Instantiate and navigate to page function
            CalledPageFunction CalledPageFunction = new CalledPageFunction("Initial Data Item Value");
Imports System.Windows
Imports System.Windows.Controls
Imports System.Windows.Navigation

Namespace StructuredNavigationSample

Public Class CallingPage
    Inherits Page
    Public Sub New()
        Me.InitializeComponent()
        AddHandler Me.pageFunctionHyperlink.Click, New RoutedEventHandler(AddressOf Me.pageFunctionHyperlink_Click)
    End Sub
    Private Sub pageFunctionHyperlink_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
}
End Sub
    }
}
End Class

End Namespace

Não é necessário passar parâmetros para a página chamada. Em vez disso, você pode fazer o seguinte:

Mas, como você verá em breve, você ainda precisará usar código para instanciar e navegar até a página chamada para coletar os dados retornados pela página chamada. Por esse motivo, o precisa ser mantido vivo, caso contrário, na próxima vez que você navegar para o , o WPF instanciará o usando o PageFunction<T>PageFunction<T>PageFunction<T> construtor sem parâmetros.

No entanto, antes que a página chamada possa retornar, ela precisa retornar dados que podem ser recuperados pela página chamadora.

Retornando o resultado da tarefa e os dados de tarefa de uma tarefa para uma página chamadora

Quando o usuário tiver terminado de usar a página chamada, ao pressionar os botões OK ou Cancelar neste exemplo, 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ções:

  1. Se o usuário cancelou a página chamada (pressionando o botão OK ou o botão Cancelar neste exemplo). Isso permite que a página chamadora determine se deve processar os dados que a página chamadora obteve do usuário.

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

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

using System;
using System.Windows;
using System.Windows.Navigation;

namespace StructuredNavigationSample
{
    public partial class CalledPageFunction : PageFunction<String>
    {
Imports System.Windows
Imports System.Windows.Navigation

Namespace StructuredNavigationSample

Public Class CalledPageFunction
    Inherits PageFunction(Of 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);
        }
    }
}
    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

Neste exemplo, se um usuário pressiona o botão Cancelar, um valor de null é retornado para a página chamadora. Se, em vez disso, o botão OK for pressionado, será retornado o valor de cadeia de caracteres fornecido pelo usuário. OnReturn é um protected virtual método que você chama para retornar seus dados à página de chamada. Seus dados precisam ser empacotados em uma instância do tipo genérico ReturnEventArgs<T> , cujo argumento type especifica o tipo de valor que Result retorna. Dessa forma, quando você declara um com um argumento de tipo específico, você está afirmando que um PageFunction<T>PageFunction<T> retornará uma instância do tipo especificado pelo argumento type. Neste exemplo, o argumento type e, consequentemente, o valor de retorno é do tipo String.

Quando OnReturn é chamada, a página de chamada precisa de alguma forma de receber o valor de retorno do PageFunction<T>. Por esse motivo, PageFunction<T> implementa o Return evento para chamar páginas para manipular. Quando OnReturn é chamado, é gerado, Return para que a página de chamada possa se registrar para Return receber a notificação.

using System.Windows;
using System.Windows.Controls;
using System.Windows.Navigation;

namespace StructuredNavigationSample
{
    public partial class CallingPage : Page
    {
Imports System.Windows
Imports System.Windows.Controls
Imports System.Windows.Navigation

Namespace StructuredNavigationSample

Public Class CallingPage
    Inherits 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;
            }
        }
    }
}
    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

Removendo páginas de tarefa quando uma tarefa é concluída

Quando uma página chamada retorna, e o usuário não cancelou a página chamada, a página chamadora processará os dados fornecidos pelo usuário e também os retornados pela página chamada. A aquisição de dados dessa forma costuma ser uma atividade isolada. Quando a página chamada retorna, a página chamadora precisa criar e navegar até uma nova página chamadora para capturar mais dados.

No entanto, a menos que uma página chamada seja removida do diário, um usuário poderá navegar de volta para uma instância anterior da página chamadora. Se um PageFunction<T> é retido no diário é determinado pela RemoveFromJournal propriedade. Por padrão, uma função de página é removida automaticamente quando OnReturn é chamada porque RemoveFromJournal está definida como true. Para manter uma função de página no histórico de navegação depois OnReturn de chamada, 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 de chamada/retorno. Essa base fornece a capacidade para criar tipos mais complexos de navegação estruturada.

Por exemplo, algumas vezes várias páginas são exigidas pela página chamadora, para obter dados suficientes de um usuário ou para realizar uma tarefa. O uso de várias páginas é conhecido como um "assistente".

Em outros casos, os aplicativos podem ter topologias complexas de navegação que dependem da navegação estruturada para operar com eficiência. Para obter mais informações, consulte Visão geral de topologias de navegação.

Confira também