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:
È 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:
Dalla pagina chiamante:
Creare un'istanza di chiamata PageFunction<T> usando il costruttore senza parametri.
Archiviare i parametri in Properties.
Passare all'oggetto denominato PageFunction<T>.
Dall'oggetto denominato PageFunction<T>:
- Recuperare e usare i parametri archiviati in Properties.
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:
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.
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
.NET Desktop feedback