Cenni preliminari sulla navigazione strutturata

Il contenuto che può essere ospitato da un'applicazione browser XAML (XBAP), un Frameoggetto o NavigationWindow è costituito da pagine che possono essere identificate da URI (Uniform Resource Identifier) e a cui si accede tramite collegamenti ipertestuali. La struttura della pagine e i modi in cui è possibile spostarsi tra di esse, definiti dai collegamenti ipertestuali, costituiscono una topologia di navigazione. Tale topologia è adatta a vari tipi di applicazioni, in particolare a quelli che consentono di spostarsi tra documenti. Per tali applicazioni, l'utente può spostarsi da una pagina all'altra senza che una pagina disponga di informazioni sull'altra.

Tuttavia, altri tipi di applicazioni presentano pagine che necessitano di informazioni su quando avviene la navigazione tra di esse. Ad esempio, si consideri un'applicazione di risorse umane che include una pagina in cui vengono elencati tutti i dipendenti di un'azienda - la pagina "Elenco dipendenti". Questa pagina può inoltre consentire agli utenti di aggiungere un nuovo dipendente facendo clic su un collegamento ipertestuale. Quando si fa clic su tale collegamento, si passa alla pagina "Aggiungi dipendente" in cui vengono raccolti i dettagli sul nuovo dipendente e quindi si torna alla pagina "Elenco dipendenti" in cui viene creato il nuovo dipendente e aggiornato l'elenco. Questo stile di navigazione è simile alla chiamata di un metodo per l'esecuzione di una determinata elaborazione e la restituzione di un valore, denominata programmazione strutturata. Analogamente, questo stile di navigazione è denominato navigazione strutturata.

La Page classe non implementa il supporto per la navigazione strutturata. Al contrario, la PageFunction<T> classe deriva da Page e la estende con i costrutti di base necessari per la navigazione strutturata. In questo argomento viene illustrato come stabilire una struttura di spostamento tramite PageFunction<T>.

Navigazione strutturata

Quando una pagina chiama un'altra pagina in una navigazione strutturata, sono richiesti alcuni o tutti i comportamenti seguenti:

  • La pagina chiamante si sposta sulla pagina chiamata, facoltativamente passando i parametri richiesti dalla pagina chiamata.

  • La pagina chiamata, quando l'utente completa l'uso della pagina chiamante, ritorna specificamente alla pagina chiamante e facoltativamente:

    • Restituisce informazioni sullo stato che descrivono come è stata completata la pagina chiamante (ad esempio, se l'utente ha premuto il pulsante OK o Annulla).

    • Restituisce i dati raccolti dall'utente (ad esempio, i dettagli sul nuovo dipendente).

  • Quando la pagina chiamate ritorna alla pagina chiamata, la pagina chiamata viene rimossa dalla cronologia di navigazione per isolare le istanze della pagina chiamata l'una dall'altra.

Questi comportamenti sono illustrati nella figura seguente:

Screenshot shows the flow between calling page and called page.

È possibile implementare questi comportamenti usando come PageFunction<T> pagina chiamata.

Navigazione strutturata con PageFunction

In questo argomento viene illustrato come implementare i meccanismi di base della navigazione strutturata che coinvolgono un singolo PageFunction<T>oggetto . In questo esempio un oggetto chiama un PagePageFunction<T> oggetto per ottenere un String valore dall'utente e restituirlo.

Creazione di una pagina chiamante

La pagina che chiama un PageFunction<T> oggetto può essere o Page .PageFunction<T> In questo esempio si tratta di un Pageoggetto , come illustrato nel codice seguente.

<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

Creazione di una funzione pagina per la chiamata

Poiché la pagina chiamante può usare la pagina chiamata per raccogliere e restituire dati dall'utente, PageFunction<T> viene implementata come classe generica il cui argomento di tipo specifica il tipo del valore restituito dalla pagina chiamata. Il codice seguente illustra l'implementazione iniziale della pagina chiamata, usando un PageFunction<T>oggetto , che restituisce un oggetto String.

<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

La dichiarazione di un PageFunction<T> oggetto è simile alla dichiarazione di un Page oggetto con l'aggiunta degli argomenti di tipo. Come si può notare nell'esempio di codice, gli argomenti di tipo vengono specificati sia nel markup XAML, usando l'attributo che il code-behind, usando la sintassi standard dell'argomento x:TypeArguments di tipo generico.

Non è necessario usare solo le classi .NET Framework come argomenti di tipo. È PageFunction<T> possibile chiamare un oggetto per raccogliere dati specifici del dominio astratti come tipo personalizzato. Nel codice seguente viene illustrato come usare un tipo personalizzato come argomento di tipo per un oggetto PageFunction<T>.

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

Gli argomenti di tipo per forniscono PageFunction<T> le basi per la comunicazione tra una pagina chiamante e la pagina chiamata, descritte nelle sezioni seguenti.

Come si vedrà, il tipo identificato con la dichiarazione di un PageFunction<T> svolge un ruolo importante nella restituzione di dati da una PageFunction<T> alla pagina chiamante.

Chiamata di PageFunction e passaggio di parametri

Per chiamare una pagina, la pagina chiamante deve creare un'istanza della pagina chiamata e passare a essa usando il Navigate metodo . Ciò consente alla pagina chiamante di passare i dati iniziali alla pagina chiamata, ad esempio i valori predefiniti per i dati raccolti dalla pagina chiamata.

Il codice seguente mostra la pagina chiamata con un costruttore senza parametri per accettare i parametri dalla pagina chiamante.

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

Il codice seguente mostra la pagina chiamante che gestisce l'evento di Hyperlink per creare un'istanza Click della pagina chiamata e passarlo a un valore stringa iniziale.

<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

Non è necessario passare parametri alla pagina chiamata. In alternativa, è possibile eseguire quanto segue:

Tuttavia, come si vedrà successivamente, è comunque necessario usare il codice per creare un'istanza della pagina chiamata e spostarsi su di essa per raccogliere i dati restituiti dalla pagina chiamata. Per questo motivo, l'oggetto PageFunction<T> deve essere mantenuto attivo; in caso contrario, la volta successiva che si passa a PageFunction<T>, WPF crea un'istanza di PageFunction<T> usando il costruttore senza parametri.

Prima che sia possibile la restituzione della pagina chiamata, questa deve restituire i dati che possono essere recuperati dalla pagina chiamante.

Restituzione del risultato dell'attività e dei dati dell'attività da un'attività a una pagina chiamante

Al termine dell'uso della pagina chiamata da parte dell'utente, indicato in questo esempio dalla pressione dei pulsanti OK o Annulla, è necessaria la restituzione della pagina chiamata. Dal momento che la pagina chiamante ha usato la pagina chiamata per raccogliere dati dall'utente, la pagina chiamante richiede due tipi di informazioni:

  1. Se l'utente ha annullato la pagina chiamante (premendo il pulsante OK o il pulsante Annulla in questo esempio). Ciò consente alla pagina chiamante di determinare se elaborare i dati che la pagina chiamante ha raccolto dall'utente.

  2. I dati immessi dall'utente.

Per restituire informazioni, PageFunction<T> implementa il OnReturn metodo . Il codice seguente illustra come chiamarlo.

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

In questo esempio se un utente preme il pulsante Annulla, viene restituito alla pagina chiamante un valore di null. Se invece viene premuto il pulsante OK, viene restituito il valore di stringa immesso dall'utente. OnReturn è un protected virtual metodo che si chiama per restituire i dati alla pagina chiamante. I dati devono essere inseriti in un pacchetto in un'istanza del tipo generico ReturnEventArgs<T> , il cui argomento di tipo specifica il tipo di valore restituito Result . In questo modo, quando si dichiara un oggetto con un PageFunction<T> argomento di tipo specifico, si indica che verrà PageFunction<T> restituita un'istanza del tipo specificato dall'argomento type. In questo esempio, l'argomento di tipo e, di conseguenza, il valore restituito è di tipo String.

Quando OnReturn viene chiamato , la pagina chiamante richiede un modo per ricevere il valore restituito PageFunction<T>di . Per questo motivo, PageFunction<T> implementa l'evento Return per chiamare le pagine da gestire. Quando OnReturn viene chiamato, Return viene generato, in modo che la pagina chiamante possa registrarsi con Return per ricevere la notifica.

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

Rimozione delle pagine di attività al completamento di un'attività

Al momento della restituzione di una pagina chiamata, se l'utente non la annulla, la pagina chiamante elabora i dati immessi dall'utente e restituiti dalla pagina chiamata. Questo tipo di acquisizione dati è in genere un'attività isolata. Al momento della restituzione della pagina chiamata, la pagina chiamante deve creare una nuova pagina chiamante e spostarsi su di essa per acquisire altri dati.

Tuttavia, a meno che la pagina chiamata non venga rimossa dal journal, l'utente potrà spostarsi nuovamente su un'istanza precedente della pagina chiamante. Se un PageFunction<T> oggetto viene conservato nel journal è determinato dalla RemoveFromJournal proprietà . Per impostazione predefinita, una funzione di pagina viene rimossa automaticamente quando OnReturn viene chiamata perché RemoveFromJournal è impostata su true. Per mantenere una funzione di pagina nella cronologia di navigazione dopo OnReturn la chiamata, impostare su RemoveFromJournalfalse.

Altri tipi di navigazione strutturata

In questo argomento viene illustrato l'uso più semplice di un oggetto PageFunction<T> per supportare la navigazione strutturata di chiamata/restituzione. Partendo da questo fondamento è possibile creare tipi più complessi di navigazione strutturata.

Ad esempio, talvolta una pagina chiamante richiede più pagine per raccogliere dati sufficienti da un utente o per eseguire un'attività. L'uso di più pagine è indicato come "procedura guidata".

In altri casi, le applicazioni possono presentare topologie di navigazione complesse il cui corretto funzionamento dipende dalla navigazione strutturata. Per altre informazioni vedere Cenni preliminari sulle topologie di navigazione.

Vedi anche