Vue d'ensemble de la navigation structurée
Le contenu qui peut être hébergé par une XAML browser application (XBAP), un Frame ou un NavigationWindow est composé de pages pouvant être identifiées par uniform resource identifiers (URIs) à en-tête pack et accédées à l'aide de liens hypertexte. La structure des pages et les méthodes permettant de les parcourir (définies par des liens hypertexte) correspondent à la topologie de navigation. Une topologie est adaptée à divers types d'applications, plus particulièrement celles qui parcourent des documents. En ce qui concerne ces applications, l'utilisateur peut passer d'une page à l'autre sans qu'il y ait de lien entre ces deux pages.
Toutefois, d'autres types d'applications comportent des pages qui doivent savoir quand l'utilisateur est passé d'une page à l'autre. Prenons, par exemple, une application de ressources humaines qui comporte une page répertoriant tous les employés d'une organisation (la page " Liste des employés "). Cette page peut également permettre à l'utilisateur d'ajouter un nouvel employé en cliquant sur un lien hypertexte. L'utilisateur passe alors à une page " Ajouter un employé ", qui rassemble les détails du nouvel employé, puis revient à la page " Liste des employés " pour créer l'employé et mettre la liste à jour. Ce style de navigation est semblable à l'appel d'une méthode permettant d'effectuer un traitement et de retourner une valeur (" programmation structurée "). En tant que tel, ce style de navigation est appelé " navigation structurée ".
La classe Page n'implémente pas la prise en charge de la navigation structurée. En lieu et place, la classe PageFunction<T> est dérivée de Page et l'étend avec les constructions de base requises pour la navigation structurée. Cette rubrique explique comment définir une navigation structurée à l'aide de PageFunction<T>.
Cette rubrique comprend les sections suivantes.
- Navigation structurée
- Navigation structurée avec PageFunction
- Autres types de navigation structurée
- Rubriques connexes
Navigation structurée
Lorsqu'une page en appelle une autre dans une navigation structurée, une partie ou l'ensemble des comportements suivants sont requis :
La page appelante accède à la page appelée et passe éventuellement les paramètres requis par la page appelée.
Lorsque l'utilisateur a terminé d'utiliser la page appelante, la page appelée revient à la page appelante et, éventuellement :
Retourne les informations d'état qui décrivent comment l'utilisateur a quitté la page appelante (par exemple, en appuyant sur un bouton OK ou Annuler).
Retourne les données recueillies par l'utilisateur (par exemple, détails d'un nouvel employé).
Lorsque la page appelante revient à la page appelée, celle-ci est supprimée de l'historique de navigation afin d'isoler les différentes instances d'une page appelée.
Ces comportements sont illustrés par la figure suivante.
Vous pouvez implémenter ces comportements en utilisant un PageFunction<T> comme page appelée.
Navigation structurée avec PageFunction
Cette rubrique indique comment implémenter les mécanismes de base de la navigation structurée avec un seul PageFunction<T>. Dans cet exemple, un Page appelle un PageFunction<T> pour obtenir et retourner une valeur String fournie par l'utilisateur.
Création d'une page appelante
La page qui appelle un PageFunction<T> peut être Page ou PageFunction<T>. Dans cet exemple, il s'agit de Page, comme indiqué dans le code suivant.
<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();
...
}
...
}
}
Création d'une fonction de page à appeler
La page appelante pouvant utiliser la page appelée pour recueillir et retourner des données fournies par l'utilisateur, PageFunction<T> est implémenté comme classe générique dont l'argument de type détermine le type de la valeur retournée par la page appelée. Le code suivant indique l'implémentation initiale de la page appelée à l'aide d'un PageFunction<T> qui retourne 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();
}
...
}
}
La déclaration d'un PageFunction<T> est semblable à celle d'un Page avec ajout des arguments de type. Comme vous pouvez le constater dans l'exemple de code, les arguments de type sont spécifiés dans une balise XAML, à l'aide de l'attribut x:TypeArguments, et dans un code-behind, à l'aide de la syntaxe d'argument de type générique standard.
Vous ne devez pas utiliser uniquement des classes .NET Framework comme arguments de type. Un PageFunction<T> peut être appelé pour rassembler des données spécifiques du domaine qui sont abstraites en tant que type personnalisé. Le code suivant indique comment utiliser un type personnalisé en tant qu'argument de type pour PageFunction<T>.
Public Class CustomType
...
End Class
namespace SDKSample
{
public class CustomType
{
...
}
}
<PageFunction
xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:SDKSample"
x:Class="SDKSample.CustomTypePageFunction"
x:TypeArguments="local:CustomType">
...
</PageFunction>
Partial Public Class CustomTypePageFunction
Inherits System.Windows.Navigation.PageFunction(Of CustomType)
using System.Windows.Navigation; // PageFunction
namespace SDKSample
{
public partial class CustomTypePageFunction : PageFunction<CustomType>
{
Les arguments de type pour PageFunction<T> fournissent la fondation pour la communication entre une page appelante et la page appelée, abordée dans les sections suivantes.
Comme vous le constaterez, le type identifié par la déclaration d'un PageFunction<T> joue un rôle important pour retourner des données d'un PageFunction<T> à la page appelante.
Appel de PageFunction et passage de paramètres
Pour appeler une page, la page appelante doit instancier la page appelée et y accéder à l'aide de la méthode Navigate. La page appelante peut ainsi passer les données initiales à la page appelée, comme les valeurs par défaut des données recueillies par la page appelée.
Le code suivant affiche la page appelée avec un constructeur non défini par défaut permettant d'accepter les paramètres de la page appelante.
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;
}
...
}
}
Le code suivant affiche la page appelante qui gère l'événement Click du Hyperlink pour instancier la page appelée et lui passer une valeur de chaîne initiale.
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()
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
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();
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");
...
}
...
}
}
<Hyperlink Name="pageFunctionHyperlink">Call Page Function</Hyperlink>
Vous n'êtes pas obligé de passer des paramètres à la page appelée. Vous pouvez plutôt effectuer les opérations suivantes :
À partir de la page appelante :
Instancier le PageFunction<T> appelé à l'aide du constructeur par défaut.
Stocker les paramètres dans Properties.
Naviguer jusqu'au PageFunction<T> appelé.
À partir du PageFunction<T> appelé :
- Récupérer et utiliser les paramètres stockés dans Properties.
Cependant, comme vous le constaterez bientôt, vous devez toujours utiliser du code pour instancier la page appelée et pour y accéder afin de recueillir les données retournées par la page appelée. Pour cette raison, PageFunction<T> doit rester actif, sinon, la prochaine fois que vous accédez à PageFunction<T>, WPF instancie PageFunction<T> à l'aide du constructeur par défaut.
Toutefois, pour que la page appelée puisse être retournée, elle doit d'abord retourner des données qui peuvent être récupérées par la page appelante.
Retour de résultats et de données de tâche à partir d'une tâche vers une page appelante
Une fois que l'utilisateur a terminé d'utiliser la page appelée (opération indiquée dans cet exemple par l'activation du bouton OK ou Annuler), celle-ci doit être retournée. Comme la page appelante a utilisé la page appelée pour recueillir les données de l'utilisateur, elle nécessite deux types d'informations :
Annulation de la page appelée par l'utilisateur (en cliquant sur le bouton OK ou Annuler, dans cet exemple). La page appelante peut ainsi déterminer si les données qu'elle a recueillies auprès de l'utilisateur doivent être traitées.
Données fournies par l'utilisateur.
Pour retourner des informations, PageFunction<T> implémente la méthode OnReturn. Le code suivant indique comment l'appeler.
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);
}
}
}
Dans cet exemple, si l'utilisateur clique sur le bouton Annuler, la valeur null est retournée à la page appelante. Si vous appuyez sur le bouton OK à la place, la valeur de chaîne fournie par l'utilisateur est retournée. OnReturn est une méthode protected virtual que vous appelez pour retourner vos données à la page appelante. Les données doivent être empaquetées dans une instance du type générique ReturnEventArgs<T>, dont l'argument de type spécifie le type de valeur retournée par Result. De cette manière, lorsque vous déclarez PageFunction<T> avec un argument de type particulier, vous indiquez que PageFunction<T> retourne une instance du type spécifié par l'argument de type. Dans cet exemple, l'argument de type et, par conséquent, la valeur de retour sont du type String.
Lorsque OnReturn est appelé, la page appelante doit pouvoir recevoir la valeur de retour de PageFunction<T>. Pour cette raison, PageFunction<T> implémente l'événement Return que les pages appelantes peuvent gérer. Lorsque OnReturn est appelé, Return est déclenché, ce qui permet à la page appelante de s'inscrire avec Return pour recevoir la notification.
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;
}
}
}
}
Suppression de pages de tâche lorsqu'une tâche est terminée
Lorsqu'une page appelée est retournée, si l'utilisateur n'a pas annulé la page appelée, la page appelante traite les données fournies par l'utilisateur et retournées par la page appelée. En règle générale, ce type d'acquisition de données est une opération isolée. Lorsque la page appelée est retournée, la page appelante doit créer une autre page appelante et y accéder pour capturer davantage de données.
Toutefois, un utilisateur peut revenir à une instance précédente de la page appelante, sauf si une page appelée est supprimée du journal. La propriété RemoveFromJournal détermine si un PageFunction<T> est conservé dans le journal. Par défaut, une fonction de page est automatiquement supprimée lorsque OnReturn est appelé, car RemoveFromJournal a la valeur true. Pour conserver une fonction de page dans l'historique de navigation après l'appel de OnReturn, définissez RemoveFromJournal sur la valeur false.
Autres types de navigation structurée
Cette rubrique illustre l'utilisation la plus élémentaire de PageFunction<T> pour assurer la prise en charge de la navigation structurée par appel/retour. Cette base vous permet de créer des types de navigation structurée plus complexes.
Par exemple, plusieurs pages sont parfois requises par une page appelante afin de rassembler un volume de données suffisant d'un utilisateur ou d'effectuer une tâche. L'utilisation de plusieurs pages est appelée " Assistant ".
Dans d'autres cas, une application peut présenter une topologie de navigation complexe qui nécessite une navigation structurée pour pouvoir fonctionner de manière optimale. Pour plus d'informations, consultez Vue d'ensemble des topologies de navigation.