Panoramica sulla Navigazione Strutturata
Il contenuto che può essere ospitato da un'applicazione browser XAML (XBAP), un Frameo un NavigationWindow è costituito da pagine che possono essere identificate da URI (Uniform Resource Identifier) e raggiunte tramite collegamenti ipertestuali. La struttura delle pagine e i modi in cui è possibile spostarsi, come definito dai collegamenti ipertestuali, è nota come topologia di navigazione. Tale topologia si adatta a un'ampia gamma di tipi di applicazione, in particolare quelli che si spostano tra i documenti. Per tali applicazioni, l'utente può spostarsi da una pagina a un'altra senza dover sapere nulla sull'altro.
Tuttavia, altri tipi di applicazioni hanno pagine che hanno bisogno di sapere quando si è navigato tra di esse. Si consideri, ad esempio, un'applicazione di risorse umane con una pagina per elencare tutti i dipendenti di un'organizzazione, ovvero la pagina "Elenca dipendenti". Questa pagina può anche consentire agli utenti di aggiungere un nuovo dipendente facendo clic su un collegamento ipertestuale. Quando si fa clic, la pagina passa a una pagina "Aggiungi un dipendente" per raccogliere i dettagli del nuovo dipendente e restituirli alla pagina "Elenca dipendenti" per creare il nuovo dipendente e aggiornare l'elenco. Questo stile di navigazione è simile alla chiamata di un metodo per eseguire alcune elaborazioni e restituire un valore, noto come programmazione strutturata. Di conseguenza, questo stile di navigazione è noto come navigazione strutturata.
La classe Page non implementa il supporto per lo spostamento strutturato. Al contrario, la classe PageFunction<T> deriva da Page e la estende con i costrutti di base necessari per la navigazione strutturata. Questo argomento illustra come stabilire una navigazione strutturata tramite PageFunction<T>.
Navigazione Strutturata
Quando una pagina chiama un'altra pagina in uno spostamento strutturato, sono necessari alcuni o tutti i comportamenti seguenti:
La pagina chiamante passa alla pagina chiamata, passando facoltativamente i parametri richiesti dalla pagina chiamata.
La pagina di destinazione, quando un utente ha finito di utilizzare la pagina di origine, ritorna alla pagina di origine, se necessario:
Restituzione di informazioni sullo stato che descrivono come è stata completata la pagina chiamante, ad esempio se un utente ha premuto un pulsante OK o un pulsante Annulla.
Restituzione di tali dati raccolti dall'utente (ad esempio, nuovi dettagli dei dipendenti).
Quando la pagina chiamante torna alla pagina chiamata, la pagina chiamata viene rimossa dalla cronologia di navigazione per isolare un'istanza di una pagina chiamata da un'altra.
Questi comportamenti sono illustrati nella figura seguente:
È possibile implementare questi comportamenti usando un PageFunction<T> come pagina chiamata.
Strutturata navigazione con PageFunction
In questo argomento viene illustrato come implementare i meccanismi di base di navigazione strutturata che coinvolgono un singolo PageFunction<T>. In questo esempio un Page chiama un PageFunction<T> per ottenere un valore String dall'utente e restituirlo.
Creazione di una pagina di chiamata
La pagina che chiama un PageFunction<T> può essere un Page o un PageFunction<T>. In questo esempio si tratta di un Page, 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 di pagina da chiamare
Poiché la pagina chiamante può utilizzare 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>, che restituisce un 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> è simile alla dichiarazione di un Page con l'aggiunta degli argomenti di tipo. Come puoi vedere dall'esempio di codice, gli argomenti di tipo vengono specificati sia nel markup XAML, usando l’attributo x:TypeArguments
, sia nel file code-behind, usando la sintassi standard degli argomenti di tipo generico.
Non è necessario usare solo le classi .NET Framework come argomenti di tipo. È possibile effettuare una chiamata a un PageFunction<T> 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 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 il PageFunction<T> forniscono le basi per la comunicazione tra una pagina chiamante e la pagina chiamata, descritte nelle sezioni seguenti.
Come vedrai, il tipo identificato con la dichiarazione di un PageFunction<T> svolge un ruolo importante nel trasferimento di dati da un PageFunction<T> alla pagina chiamante.
Chiamare una PageFunction e passare parametri
Per chiamare una pagina, la pagina chiamante deve creare un'istanza della pagina chiamata e navigare verso di essa usando il metodo Navigate. 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
Nel codice seguente viene illustrata la pagina chiamante che gestisce l'evento Click del Hyperlink per istanziare la pagina chiamata e passarle un valore iniziale di tipo stringa.
<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. È invece possibile eseguire le operazioni seguenti:
Dalla pagina chiamante:
Creare un'istanza 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à a breve, sarà comunque necessario usare il codice per creare un'istanza e passare alla pagina chiamata per raccogliere i dati restituiti dalla pagina chiamata. Per questo motivo, il PageFunction<T> deve essere mantenuto attivo; in caso contrario, la volta successiva che si naviga alla PageFunction<T>, WPF crea un'istanza del PageFunction<T> usando il costruttore senza parametri.
Prima che la pagina chiamata possa restituire, tuttavia, deve restituire i dati che possono essere recuperati dalla pagina chiamante.
Restituzione del risultato e dei dati di un'attività a una pagina chiamante
Al termine dell'utilizzo della pagina chiamata, indicato in questo esempio premendo i pulsanti OK o Annulla, la pagina chiamata deve tornare. Poiché la pagina chiamante ha usato la pagina chiamata per raccogliere dati dall'utente, la pagina chiamante richiede due tipi di informazioni:
Indica se l'utente ha annullato la pagina chiamata (premendo il pulsante OK o il pulsante Annulla in questo esempio). Ciò consente alla pagina chiamante di determinare se elaborare i dati raccolti dall'utente dalla pagina chiamante.
Dati forniti dall'utente.
Per restituire informazioni, PageFunction<T> implementa il metodo OnReturn. 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 un valore di null
alla pagina chiamante. Se invece viene premuto il pulsante OK, viene restituito il valore stringa fornito dall'utente.
OnReturn è un metodo protected virtual
chiamato per restituire i dati alla pagina chiamante. I tuoi dati devono essere inseriti in un'istanza del tipo generico ReturnEventArgs<T>, il cui argomento specifica il tipo di valore che Result restituisce. In questo modo, quando si dichiara un PageFunction<T> con un argomento di tipo specifico, si indica che un PageFunction<T> restituirà un'istanza del tipo specificato dall'argomento di tipo. In questo esempio, l'argomento di tipo e, di conseguenza, il valore restituito è di tipo String.
Quando viene chiamato OnReturn, la pagina chiamante richiede un modo per ricevere il valore restituito del PageFunction<T>. Per questo motivo, PageFunction<T> implementa l'evento Return per chiamare le pagine da gestire. Quando viene chiamato OnReturn, viene generato Return, 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 delle attività al termine di un'attività
Quando una pagina chiamata viene restituita e l'utente non ha annullato la pagina chiamata, la pagina chiamante elabora i dati forniti dall'utente e anche i dati restituiti dalla pagina chiamata. L'acquisizione dei dati in questo modo è in genere un'attività isolata; quando la pagina chiamata viene restituita, la pagina chiamante deve creare e passare a una nuova pagina di chiamata per acquisire più dati.
Tuttavia, a meno che una pagina chiamata non venga rimossa dal registro, un utente potrà tornare a un'istanza precedente della pagina chiamante. Se un PageFunction<T> viene conservato nel journal è determinato dalla proprietà RemoveFromJournal. Per impostazione predefinita, una funzione di pagina viene rimossa automaticamente quando viene chiamato OnReturn perché RemoveFromJournal è impostato su true
. Per mantenere una funzione di pagina nella cronologia di navigazione dopo la chiamata di OnReturn, impostare RemoveFromJournal su false
.
Altri tipi di navigazione strutturata
In questo argomento viene illustrato l'uso più semplice di un PageFunction<T> per sostenere la navigazione strutturata di chiamata e ritorno. Questa base offre la possibilità di creare tipi più complessi di navigazione strutturata.
Ad esempio, a volte più pagine sono richieste da una pagina chiamante per raccogliere dati sufficienti da un utente o per eseguire un'attività. L'uso di più pagine viene definito "procedura guidata".
In altri casi, le applicazioni possono avere topologie di navigazione complesse che dipendono dall'esplorazione strutturata per operare in modo efficace. Per ulteriori informazioni, consultare Panoramica delle topologie di spostamento.
Vedere anche
.NET Desktop feedback