Información general sobre la navegación estructurada
Artículo
Contenido que se puede hospedar en una aplicación del explorador XAML (XBAP), un Frame o una NavigationWindow se compone de páginas que pueden identificarse mediante identificadores de recursos uniformes (URI) del paquete y en las que se puede navegar mediante hipervínculos. La estructura de páginas y las formas en que se puede navegar por ellas, tal como se define mediante hipervínculos, se conoce como topología de navegación. Esta topología se adapta a diversos tipos de aplicaciones, especialmente a aquéllas que navegan por documentos. Con estas aplicaciones, el usuario puede navegar de una página a otra sin necesidad de saber nada sobre la otra.
Sin embargo, otros tipos de aplicaciones tienen páginas que necesitan saber cuándo se ha navegado entre ellas. Por ejemplo, suponga una aplicación de recursos humanos que tiene una página con una lista de todos los empleados de una organización, la página "Lista de empleados". Esta página también podría permitir a los usuarios agregar a un nuevo empleado haciendo clic en un hipervínculo. Al hacer clic en ella, la página navega a una página "Agregar un empleado" para recopilar los datos del nuevo empleado y llevarlos a la página "Lista de empleados" para crear al nuevo empleado y actualizar la lista. Este estilo de navegación es similar a llamar a un método para realizar algún procesamiento y devolver un valor, que se conoce como programación estructurada. Por tanto, este estilo de navegación se conoce como navegación estructurada.
La clase Page no implementa la compatibilidad con la navegación estructurada. En su lugar, la clase PageFunction<T> se deriva de Page y se extiende con las estructuras básicas requeridas para la navegación estructurada. Este tema muestra cómo establecer una navegación estructurada mediante PageFunction<T>.
Navegación estructurada
Cuando una página llama a otra página en una navegación estructurada, se requieren algunos o todos los comportamientos siguientes:
La página que llama navega a la página llamada y, opcionalmente, pasa los parámetros requeridos por la página llamada.
La página llamada, cuando un usuario ha terminado de usar la página que llama, vuelve específicamente a la página que llama y, opcionalmente:
Devuelve información de estado que describe cómo se completó la página que llama (por ejemplo, si un usuario presionó un botón Aceptar o Cancelar).
Devuelve los datos recopilados del usuario (por ejemplo, los datos de un nuevo empleado).
Cuando se devuelve la página que llama a la página llamada, la página llamada se quita del historial de navegación para aislar cada instancia de una página llamada de otra.
En la ilustración siguiente se muestran estos comportamientos:
Captura de pantalla que muestra el flujo entre la página que llama y la página a la que se llama.
Puede implementar estos comportamientos usando una clase PageFunction<T> como página llamada.
Navegación estructurada con PageFunction
Este tema muestra cómo implementar los mecanismos básicos de navegación estructurada que implica un solo elemento PageFunction<T>. En este ejemplo, una clase Page llama a una clase PageFunction<T> para obtener un valor String del usuario y devolverlo.
Creación de una página que llama
La página que llama a una clase PageFunction<T> puede ser una clase Page o PageFunction<T>. En este ejemplo, es una clase Page, como se muestra en el código siguiente.
using System.Windows;
using System.Windows.Controls;
using System.Windows.Navigation;
namespaceStructuredNavigationSample
{
publicpartialclassCallingPage : Page
{
publicCallingPage()
{
InitializeComponent();
Imports System.Windows
Imports System.Windows.Controls
Imports System.Windows.Navigation
Namespace StructuredNavigationSample
Public Class CallingPage
Inherits Page
Public Sub New()
Me.InitializeComponent()
C#
}
End Sub
C#
}
}
End Class
End Namespace
Creación de una función de página para realizar la llamada
Puesto que la página que llama puede utilizar la página llamada para recopilar y devolver datos del usuario, PageFunction<T> se implementa como una clase genérica cuyo argumento de tipo especifica el tipo del valor que devolverá la página llamada. El código siguiente muestra la implementación inicial de la página llamada, con una clase PageFunction<T> que devuelve un valor String.
using System;
using System.Windows;
using System.Windows.Navigation;
namespaceStructuredNavigationSample
{
publicpartialclassCalledPageFunction : PageFunction<String>
{
publicCalledPageFunction()
{
InitializeComponent();
}
Imports System.Windows
Imports System.Windows.Navigation
Namespace StructuredNavigationSample
Public Class CalledPageFunction
Inherits PageFunction(Of String)
Public Sub New()
Me.InitializeComponent()
End Sub
C#
}
}
End Class
End Namespace
La declaración de una clase PageFunction<T> es similar a la declaración de una clase Page con la adición de los argumentos de tipo. Como puede ver en el ejemplo de código, se especifican los argumentos de tipo en el marcado XAML, con el atributo x:TypeArguments, y en el código subyacente, con la sintaxis del argumento de tipo genérico estándar.
No tiene que usar sólo clases de .NET Framework como argumentos de tipo. Una clase PageFunction<T> podría invocarse para recopilar datos específicos de dominio que se resuman como un tipo personalizado. El código siguiente muestra cómo utilizar un tipo personalizado como un argumento de tipo para una clase PageFunction<T>.
using System.Windows.Navigation;
namespaceSDKSample
{
publicpartialclassCustomTypePageFunction : PageFunction<CustomType>
{
Partial Public Class CustomTypePageFunction
Inherits System.Windows.Navigation.PageFunction(Of CustomType)
C#
}
}
End Class
Los argumentos de tipo para la clase PageFunction<T> proporciona la base para la comunicación entre una página que llama y la página llamada, que se describe en las siguientes secciones.
Como verá, el tipo que se identifica con la declaración de una clase PageFunction<T> desempeña un rol importante en la devolución de datos de una clase PageFunction<T> a la página que llama.
Llamada a una clase PageFunction y transmisión de parámetros
Para llamar a una página, la página que llama debe crear una instancia de la página llamada y navegar hasta ella mediante el método Navigate. Esto permite que la página que llama pase los datos iniciales a la página llamada, como valores predeterminados para los datos recopilados por la página llamada.
El código siguiente muestra la página llamada con un constructor que no es sin parámetros para aceptar parámetros de la página que llama.
C#
using System;
using System.Windows;
using System.Windows.Navigation;
namespaceStructuredNavigationSample
{
publicpartialclassCalledPageFunction : PageFunction<String>
{
Imports System.Windows
Imports System.Windows.Navigation
Namespace StructuredNavigationSample
Public Class CalledPageFunction
Inherits PageFunction(Of String)
Public Sub New(ByVal initialDataItem1Value As String)
Me.InitializeComponent()
C#
// Set initial valuethis.dataItem1TextBox.Text = initialDataItem1Value;
}
' Set initial value
Me.dataItem1TextBox.Text = initialDataItem1Value
End Sub
C#
}
}
End Class
End Namespace
El código siguiente muestra cómo la página que llama controla el evento Click de la clase Hyperlink para crear una instancia de la página llamada y pasarle un valor de cadena inicial.
using System.Windows;
using System.Windows.Controls;
using System.Windows.Navigation;
namespaceStructuredNavigationSample
{
publicpartialclassCallingPage : Page
{
publicCallingPage()
{
InitializeComponent();
this.pageFunctionHyperlink.Click += new RoutedEventHandler(pageFunctionHyperlink_Click);
}
voidpageFunctionHyperlink_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)
C#
}
End Sub
C#
}
}
End Class
End Namespace
No es necesario pasar parámetros a la página llamada. En su lugar, podría hacer lo siguiente:
En la página que llama:
Cree una instancia de la PageFunction<T> llamada mediante el constructor sin parámetros.
Recupere y utilice los parámetros almacenados en Properties.
Pero, como verá en breve, aún necesitará utilizar código para crear una instancia y navegar a la página llamada para recopilar los datos devueltos por la página llamada. Por esta razón, debe mantener la clase PageFunction<T> activa; de lo contrario, la próxima vez que navegue a PageFunction<T>, WPF creará una instancia de PageFunction<T> mediante el constructor sin parámetros.
Sin embargo, antes de la página llamada pueda volver, debe devolver los datos para que los pueda recuperar la página que llama.
Devolución de los resultados y los datos de la tarea de una tarea a una página que llama
Una vez que el usuario ha terminado de utilizar la página llamada, en este ejemplo indicado al presionar los botones Aceptar o Cancelar, la página llamada debe volver. Puesto que la página que llama utilizó la página llamada para recopilar datos del usuario, la página que llama requiere dos tipos de información:
Si el usuario canceló la página llamada (presionando el botón Aceptar o el botón Cancelar en este ejemplo). Esto permite que la página que llama determine si se procesan los datos que recopiló del usuario.
Los datos proporcionados por el usuario.
Para devolver información, PageFunction<T> implementa el método OnReturn. El siguiente código muestra cómo llamarlo.
C#
using System;
using System.Windows;
using System.Windows.Navigation;
namespaceStructuredNavigationSample
{
publicpartialclassCalledPageFunction : PageFunction<String>
{
Imports System.Windows
Imports System.Windows.Navigation
Namespace StructuredNavigationSample
Public Class CalledPageFunction
Inherits PageFunction(Of String)
C#
voidokButton_Click(object sender, RoutedEventArgs e)
{
// Accept when Ok button is clicked
OnReturn(new ReturnEventArgs<string>(this.dataItem1TextBox.Text));
}
voidcancelButton_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
En este ejemplo, si un usuario presiona el botón Cancelar, se devuelve un valor de null a la página que llama. En cambio, si se presiona el botón Aceptar, se devuelve el valor de cadena proporcionado por el usuario. OnReturn es un método protected virtual al que se llama para devolver los datos a la página que llama. Los datos deben empaquetarse en una instancia del tipo ReturnEventArgs<T> genérico, cuyo argumento de tipo especifica el tipo de valor que devuelve Result. De este modo, cuando se declara una clase PageFunction<T> con un argumento de tipo determinado, se indica que una clase PageFunction<T> devolverá una instancia del tipo especificado por el argumento de tipo. En este ejemplo, el argumento de tipo y, por consiguiente, el valor devuelto es de tipo String.
Cuando se llama a OnReturn, la página que llama necesita recibir de alguna manera el valor devuelto de la clase PageFunction<T>. Por este motivo, PageFunction<T> implementa el evento Return para que las páginas que llaman lo controlen. Cuando se llama a OnReturn, se genera Return, por lo que la página que llama puede registrarse en Return para recibir la notificación.
C#
using System.Windows;
using System.Windows.Controls;
using System.Windows.Navigation;
namespaceStructuredNavigationSample
{
publicpartialclassCallingPage : Page
{
Imports System.Windows
Imports System.Windows.Controls
Imports System.Windows.Navigation
Namespace StructuredNavigationSample
Public Class CallingPage
Inherits Page
C#
voidpageFunctionHyperlink_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);
}
voidpageFunction_Return(object sender, ReturnEventArgs<string> e)
{
this.pageFunctionResultsTextBlock.Visibility = Visibility.Visible;
// Display resultthis.pageFunctionResultsTextBlock.Text = (e != null ? "Accepted" : "Canceled");
// If page function returned, display result and dataif (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
Eliminación de páginas de tarea cuando se completa una tarea
Cuando vuelve una página llamada y el usuario no la había cancelado, la página que llama procesará los datos proporcionados por el usuario y los devueltos desde la página llamada. La adquisición de datos de esta manera suele ser una actividad aislada; cuando la página llamada vuelve, la página que llama debe crear y navegar a una nueva página que llama para capturar más datos.
Sin embargo, a menos que una página llamada se quite del diario, un usuario podrá volver a una instancia anterior de la página que llama. Si se conserva o no una clase PageFunction<T> en el diario está determinado por la propiedad RemoveFromJournal. De forma predeterminada, una función de página se quita automáticamente cuando se llama a OnReturn porque RemoveFromJournal está establecido en true. Para mantener una función de página en el historial de navegación después de llamar a OnReturn, establezca RemoveFromJournal en false.
Otros tipos de navegación estructurada
En este tema se muestra el uso más básico de una clase PageFunction<T> para permitir la navegación estructurada mediante llamada/devolución. Esta base proporciona la capacidad de crear tipos más complejos de navegación estructurada.
Por ejemplo, a veces son necesarias varias páginas en una página que llama para recopilar suficientes datos de un usuario o para realizar una tarea. El uso de varias páginas se conoce como un "asistente".
En otros casos, las aplicaciones pueden tener topologías de navegación complejas que dependen de la navegación estructurada para funcionar eficazmente. Para más información, consulte Información general sobre topologías de navegación.
El origen de este contenido se puede encontrar en GitHub, donde también puede crear y revisar problemas y solicitudes de incorporación de cambios. Para más información, consulte nuestra guía para colaboradores.
Comentarios de .NET Desktop feedback
.NET Desktop feedback es un proyecto de código abierto. Seleccione un vínculo para proporcionar comentarios:
Únase a la serie de reuniones para crear soluciones de inteligencia artificial escalables basadas en casos de uso reales con compañeros desarrolladores y expertos.
Obtenga información sobre la compatibilidad con la navegación de tipo explorador que se utiliza en aplicaciones independientes y aplicaciones de explorador XAML en Windows Presentation Foundation (WPF).
En este artículo, se proporciona información general sobre las topologías de navegación. Posteriormente, se tratan tres topologías de navegación comunes y se incluyen ejemplos de estas.
Aprenda a llamar a una función de página desde una página de lenguaje XAML y navegar a esa función de página mediante un identificador uniforme de recursos.