Navegación del shell de .NET MAUI
El shell .NET Multi-platform App UI (.NET MAUI) incluye una experiencia de navegación basada en URI que usa rutas para navegar a cualquier página de la aplicación, sin tener que seguir una jerarquía de navegación establecida. También ofrece la posibilidad de navegar hacia atrás sin tener que visitar todas las páginas de la pila de navegación.
La clase Shell define las siguientes propiedades relacionadas con la navegación:
- BackButtonBehavior, de tipo BackButtonBehavior, una propiedad adjunta que define el comportamiento del botón Atrás.
CurrentItem
, de tipoShellItem
, el valor seleccionado actualmente.CurrentPage
, de tipo Page, la página presentada actualmente.CurrentState
, de tipoShellNavigationState
, el estado de navegación actual de Shell.Current
, de tipo Shell, que proporciona acceso al shell actual.
Las propiedades BackButtonBehavior, CurrentItem
y CurrentState
están respaldadas por objetos BindableProperty, lo que significa que estas propiedades pueden ser destinos de los enlaces de datos.
La navegación se realiza mediante la invocación del método GoToAsync, desde la clase Shell. Cuando la navegación está a punto de realizarse, se activa un evento Navigating
y, cuando finaliza, se activa un evento Navigated
.
Nota:
Se puede seguir navegando entre páginas en una aplicación de Shell con la propiedad Navigation
. Para obtener más información, consulta Realizar navegación no modal.
Rutas
Para navegar en una aplicación shell, se especifica un URI al que navegar. Los URI de navegación pueden tener tres componentes:
- Una ruta, que define la ruta de acceso al contenido que existe como parte de la jerarquía visual de Shell.
- Una página. Las páginas que no existen en la jerarquía visual de shell se pueden insertar en la pila de navegación desde cualquier lugar dentro de una aplicación shell. Por ejemplo, una página de detalles no se definirá en la jerarquía visual de Shell, pero se puede insertar en la pila de navegación si es necesario.
- Uno o varios parámetros de consulta. Los parámetros de consulta son parámetros que se pueden pasar a la página de destino durante la navegación.
Cuando un URI de navegación incluye los tres componentes, la estructura es: //route/page?queryParameters
Registro de rutas
Se pueden definir rutas en objetos FlyoutItem, TabBar, Tab y ShellContent mediante sus propiedades Route
:
<Shell ...>
<FlyoutItem ...
Route="animals">
<Tab ...
Route="domestic">
<ShellContent ...
Route="cats" />
<ShellContent ...
Route="dogs" />
</Tab>
<ShellContent ...
Route="monkeys" />
<ShellContent ...
Route="elephants" />
<ShellContent ...
Route="bears" />
</FlyoutItem>
<ShellContent ...
Route="about" />
...
</Shell>
Nota:
Todos los elementos de la jerarquía de Shell tienen asociada una ruta. Si no se establece una ruta, se genera una en tiempo de ejecución. Pero no se garantiza que las rutas generadas sean coherentes entre distintas sesiones de aplicación.
En el ejemplo anterior se crea la siguiente jerarquía de ruta, que se puede usar en la navegación mediante programación:
animals
domestic
cats
dogs
monkeys
elephants
bears
about
Para desplazarse al objeto ShellContent de la ruta dogs
, el URI de la ruta absoluta es //animals/domestic/dogs
. Igualmente, para desplazarse al objeto ShellContent de la ruta about
, el URL de la ruta absoluta es //about
.
Advertencia
Si se detecta una ruta duplicada, se produce ArgumentException
al inicio de la aplicación. También se producirá esta excepción si dos o más rutas del mismo nivel de la jerarquía comparten el nombre de ruta.
Registro de rutas de la página de detalles
En el constructor de subclases de Shell, o en cualquier otra ubicación que se ejecute antes de invocar una ruta, se pueden registrar explícitamente rutas adicionales para cualquier página que no esté representada en la jerarquía visual de Shell. Esto se realiza mediante el método Routing.RegisterRoute
:
Routing.RegisterRoute("monkeydetails", typeof(MonkeyDetailPage));
Routing.RegisterRoute("beardetails", typeof(BearDetailPage));
Routing.RegisterRoute("catdetails", typeof(CatDetailPage));
Routing.RegisterRoute("dogdetails", typeof(DogDetailPage));
Routing.RegisterRoute("elephantdetails", typeof(ElephantDetailPage));
En este ejemplo se registran como rutas páginas de detalles que no están definidas en la subclase Shell. Se puede navegar después a estas páginas de detalles desde cualquier lugar de la aplicación con la navegación basada en URI. Las rutas de estas páginas se conocen como rutas globales.
Advertencia
Se producirá una excepción ArgumentException
si el método Routing.RegisterRoute
intenta registrar la misma ruta en dos o más tipos diferentes.
Como alternativa, se pueden registrar las páginas en diferentes jerarquías de ruta:
Routing.RegisterRoute("monkeys/details", typeof(MonkeyDetailPage));
Routing.RegisterRoute("bears/details", typeof(BearDetailPage));
Routing.RegisterRoute("cats/details", typeof(CatDetailPage));
Routing.RegisterRoute("dogs/details", typeof(DogDetailPage));
Routing.RegisterRoute("elephants/details", typeof(ElephantDetailPage));
En este ejemplo se habilita la navegación contextual por las páginas, donde la navegación a la ruta details
desde la página de la ruta monkeys
muestra MonkeyDetailPage
. De forma similar, al desplazarse a la ruta details
desde la página de la ruta elephants
se muestra ElephantDetailPage
. Para obtener más información, consulte Navegación contextual.
Nota:
Si es necesario, el registro de las páginas cuyas rutas se han registrado con el método Routing.RegisterRoute
se puede cancelar con el método Routing.UnRegisterRoute
.
Realización de la navegación
Para realizar la navegación, se debe obtener primero una referencia a la subclase Shell. Esta referencia se puede obtener a través de la Shell.Current
propiedad . La navegación se puede realizar entonces llamando al método GoToAsync en el objeto Shell. Este método lleva a una clase ShellNavigationState
y devuelve un objeto Task
que se completa una vez completada la animación de navegación. El objeto ShellNavigationState
se construye mediante el método GoToAsync, desde una propiedad string
o Uri
, y tiene su propiedad Location
establecida en el argumento string
o Uri
.
Importante
Cuando se navega a una ruta de la jerarquía visual de Shell, no se crea una pila de navegación. Sin embargo, cuando se navega a una página que no está en la jerarquía visual de Shell, se crea una pila de navegación.
El estado actual de navegación del objeto Shell se puede recuperar mediante la propiedad Shell.Current.CurrentState
, que incluye el URI de la ruta mostrada en la propiedad Location
.
Rutas absolutas
La navegación se puede realizar mediante la especificación de un URI absoluto válido como argumento del método GoToAsync:
await Shell.Current.GoToAsync("//animals/monkeys");
En este ejemplo se navega a la página de la ruta monkeys
, donde dicha ruta se define en un objeto ShellContent. El objeto ShellContent que representa la ruta monkeys
es un elemento secundario de un objeto FlyoutItem, cuya ruta es animals
.
Rutas relativas
La navegación se puede realizar también mediante la especificación de un URI relativo válido como argumento del método GoToAsync. El sistema de enrutamiento intenta hacer coincidir el URI con un objeto ShellContent. Por lo tanto, si todas las rutas de una aplicación son únicas, la navegación se puede realizar con solo especificar el nombre de ruta único como un URI relativo.
Se admiten los formatos siguientes de ruta relativa:
Formato | Descripción |
---|---|
route | En la jerarquía de ruta se buscará la ruta especificada, hacia arriba desde la posición actual. La página que coincida se insertará en la pila de navegación. |
/route | La jerarquía de ruta se buscará a partir de la ruta especificada, hacia abajo desde la posición actual. La página que coincida se insertará en la pila de navegación. |
//route | En la jerarquía de ruta se buscará la ruta especificada, hacia arriba desde la posición actual. La página que coincida reemplazará la pila de navegación. |
///route | En la jerarquía de ruta se buscará la ruta especificada, hacia abajo desde la posición actual. La página que coincida reemplazará la pila de navegación. |
En el ejemplo siguiente se navega a la página de la ruta monkeydetails
:
await Shell.Current.GoToAsync("monkeydetails");
En este ejemplo, la ruta monkeyDetails
se busca hacia arriba en la jerarquía hasta que se encuentra la página que coincide. Cuando se encuentra, se inserta en la pila de navegación.
Navegación contextual
Las rutas relativas permiten la navegación contextual. Por ejemplo, considere la siguiente jerarquía de ruta:
monkeys
details
bears
details
Cuando se muestra la página registrada para la ruta monkeys
, al navegar a la ruta details
se mostrará la página registrada para la ruta monkeys/details
. Igualmente, cuando se muestra la página registrada para la ruta bears
, al navegar a la ruta details
se mostrará la página registrada para la ruta bears/details
. Para información sobre cómo registrar las rutas en este ejemplo, consulte Registro de rutas de página.
Navegación hacia atrás
La navegación hacia atrás se puede llevar a cabo especificando ".." como argumento en el método GoToAsync:
await Shell.Current.GoToAsync("..");
La navegación hacia atrás con ".." también se puede combinar con una ruta:
await Shell.Current.GoToAsync("../route");
En este ejemplo, se realiza la navegación hacia atrás y, después, se navega a la ruta especificada.
Importante
Desplazarse hacia atrás y luego a una ruta especificada solo es posible si la navegación hacia atrás sitúa al usuario en la ubicación actual en la jerarquía de rutas para navegar a la ruta especificada.
Del mismo modo, es posible desplazarse hacia atrás varias veces y, seguidamente, navegar a una ruta especificada:
await Shell.Current.GoToAsync("../../route");
En este ejemplo, la navegación hacia atrás se realiza dos veces y, después, se navega a la ruta especificada.
Además, los datos se pueden pasar a través de las propiedades de consulta al navegar hacia atrás:
await Shell.Current.GoToAsync($"..?parameterToPassBack={parameterValueToPassBack}");
En este ejemplo, se realiza la navegación hacia atrás y el valor del parámetro de consulta se pasa al parámetro de consulta en la página anterior.
Nota:
Los parámetros de consulta se pueden anexar a cualquier solicitud de navegación hacia atrás.
Para obtener más información sobre cómo pasar datos al navegar, vea Pasar datos.
Rutas no válidas
Los siguientes formatos de ruta no son válidos:
Formato | Explicación |
---|---|
//page o ///page | Actualmente, las rutas globales no pueden ser la única página en la pila de navegación. Por lo tanto, no se admite el enrutamiento absoluto a rutas globales. |
El uso de estos formatos de ruta dará como resultado una excepción Exception
.
Advertencia
Al intentar navegar a una ruta inexistente, se producirá una excepción ArgumentException
.
Depuración de la navegación
Algunas de las clases de Shell se representan con DebuggerDisplayAttribute
, que especifica cómo el depurador muestra una clase o campo. Esto puede ayudar a depurar las solicitudes de navegación puesto que se muestran los datos relacionados con la solicitud de navegación. Por ejemplo, en la captura de pantalla siguiente se muestran las propiedades CurrentItem
y CurrentState
del objeto Shell.Current
:
En este ejemplo, la propiedad CurrentItem
, de tipo FlyoutItem, muestra el título y la ruta de acceso del objeto FlyoutItem. Igualmente, la propiedad CurrentState
, de tipo ShellNavigationState
, muestra el URI de la ruta mostrada dentro de la aplicación de Shell.
Pila de navegación
La clase Tab define una propiedad Stack
, de tipo IReadOnlyList<Page>
, que representa la pila de navegación actual dentro de Tab. La clase también proporciona los siguientes métodos reemplazables de navegación:
GetNavigationStack
, que devuelveIReadOnlyList<Page>
, la pila de navegación actual.OnInsertPageBefore
, que se llama cuando se llama aINavigation.InsertPageBefore
.OnPopAsync
, que devuelveTask<Page>
y se llama cuando se llama aINavigation.PopAsync
.OnPopToRootAsync
, que devuelveTask
y se llama cuando se llama aINavigation.OnPopToRootAsync
.OnPushAsync
, que devuelveTask
y se llama cuando se llama aINavigation.PushAsync
.OnRemovePage
, que se llama cuando se llama aINavigation.RemovePage
.
En el ejemplo siguiente se muestra cómo se invalida el método OnRemovePage
:
public class MyTab : Tab
{
protected override void OnRemovePage(Page page)
{
base.OnRemovePage(page);
// Custom logic
}
}
En este ejemplo, los objetos MyTab
se deben consumir en la jerarquía visual de Shell en lugar de los objetos Tab.
Eventos de navegación
La clase Shell define un evento Navigating
, que se desencadena cuando está a punto de realizarse la navegación, ya sea debido a la navegación mediante programación o a la interacción del usuario. El objeto ShellNavigatingEventArgs
que acompaña al evento Navigating
proporciona las siguientes propiedades:
Propiedad | Tipo | Descripción |
---|---|---|
Current |
ShellNavigationState |
Identificador URI base de la página actual. |
Source |
ShellNavigationSource |
El tipo de navegación que se ha producido. |
Target |
ShellNavigationState |
Identificador URI que representa el destino de la navegación. |
CanCancel |
bool |
Valor que indica si es posible cancelar la navegación. |
Cancelled |
bool |
Valor que indica si la navegación se ha cancelado. |
Además, la clase ShellNavigatingEventArgs
proporciona un método Cancel
, que se puede usar para cancelar la navegación, y un método GetDeferral
, que devuelve un token de ShellNavigatingDeferral
que se puede usar para completar la navegación. Para obtener más información sobre el aplazamiento de la navegación, vea Aplazamiento de navegación.
La clase Shell también define un evento Navigated
, que se desencadena cuando se ha completado la navegación. El objeto ShellNavigatedEventArgs
que acompaña al evento Navigated
proporciona las siguientes propiedades:
Propiedad | Tipo | Descripción |
---|---|---|
Current |
ShellNavigationState |
Identificador URI base de la página actual. |
Previous |
ShellNavigationState |
Identificador URI de la página anterior. |
Source |
ShellNavigationSource |
El tipo de navegación que se ha producido. |
Importante
Se llama al método OnNavigating
cuando se genera el evento Navigating
. Del mismo modo, se llama al método OnNavigated
cuando se genera el evento Navigated
. Ambos métodos se pueden invalidar en la subclase Shell para interceptar las solicitudes de navegación.
Ambas clases, ShellNavigatedEventArgs
y ShellNavigatingEventArgs
, tienen propiedades Source
, de tipo ShellNavigationSource
. Esta enumeración proporciona los valores siguientes:
Unknown
Push
Pop
PopToRoot
Insert
Remove
ShellItemChanged
ShellSectionChanged
ShellContentChanged
Por lo tanto, se puede interceptar la navegación con una invalidación de OnNavigating
y se pueden realizar acciones en función del origen de navegación. Por ejemplo, el código siguiente muestra cómo cancelar la navegación hacia atrás si no se han guardado los datos de la página:
protected override void OnNavigating(ShellNavigatingEventArgs args)
{
base.OnNavigating(args);
// Cancel any back navigation.
if (args.Source == ShellNavigationSource.Pop)
{
args.Cancel();
}
}
Aplazamiento de navegación
La navegación de shell se puede interceptar y completar, o bien cancelar, según lo que elija el usuario. Esto se puede conseguir invalidando el método OnNavigating
de la subclase Shell y llamando al método GetDeferral
en el objeto ShellNavigatingEventArgs
. Este método devuelve un token de ShellNavigatingDeferral
que tiene un método Complete
, que se puede usar para completar la solicitud de navegación:
public MyShell : Shell
{
// ...
protected override async void OnNavigating(ShellNavigatingEventArgs args)
{
base.OnNavigating(args);
ShellNavigatingDeferral token = args.GetDeferral();
var result = await DisplayActionSheet("Navigate?", "Cancel", "Yes", "No");
if (result != "Yes")
{
args.Cancel();
}
token.Complete();
}
}
En este ejemplo, se muestra una hoja de acción que invita al usuario a completar la solicitud de navegación o cancelarla. La navegación se cancela invocando el método Cancel
en el objeto ShellNavigatingEventArgs
. La navegación se completa invocando el método Complete
en el token de ShellNavigatingDeferral
obtenido mediante el método GetDeferral
en el objeto ShellNavigatingEventArgs
.
Advertencia
El método GoToAsync generará una excepción InvalidOperationException
si un usuario intenta navegar mientras hay un aplazamiento de navegación pendiente.
Pasar datos
Los datos primitivos se pueden pasar como parámetros de consulta basados en cadenas al realizar la navegación mediante programación basada en URI. Para esto, se anexa ?
después de una ruta, seguido de un identificador de parámetro de consulta, =
y un valor:
async void OnCollectionViewSelectionChanged(object sender, SelectionChangedEventArgs e)
{
string elephantName = (e.CurrentSelection.FirstOrDefault() as Animal).Name;
await Shell.Current.GoToAsync($"elephantdetails?name={elephantName}");
}
En este ejemplo se recupera el elefante actualmente seleccionado en CollectionView y se navega a la ruta elephantdetails
; además, se pasa elephantName
como parámetro de consulta.
Pasar datos de navegación basados en objetos de uso múltiple
Se pueden pasar datos de navegación basados en objetos de uso múltiple con una sobrecarga de GoToAsync que especifica un argumento IDictionary<string, object>
:
async void OnCollectionViewSelectionChanged(object sender, SelectionChangedEventArgs e)
{
Animal animal = e.CurrentSelection.FirstOrDefault() as Animal;
var navigationParameter = new Dictionary<string, object>
{
{ "Bear", animal }
};
await Shell.Current.GoToAsync($"beardetails", navigationParameter);
}
En este ejemplo se recupera el oso seleccionado actualmente en CollectionView, como Animal
. El objeto Animal
se agrega a Dictionary
con la clave Bear
. A continuación, se realiza la navegación a la ruta beardetails
, con Dictionary
que se pasa como parámetro de navegación.
Los datos que se pasan como argumento IDictionary<string, object>
se conservan en la memoria durante la vigencia de la página y no se liberan hasta que la página se quita de la pila de navegación. Esto puede ser problemático como se muestra en el escenario siguiente:
Page1
navega aPage2
usando el método GoToAsync y pasando un objeto denominadoMyData
. A continuación,Page2
recibeMyData
como parámetro de consulta.Page2
navega hastaPage3
usando el método GoToAsync, sin pasar ningún dato.Page3
navega hacia atrás con el método GoToAsync. A continuación,Page2
recibeMyData
de nuevo como parámetro de consulta.
Aunque esto es deseable en muchos escenarios, si no lo deseas, debes borrar el argumento IDictionary<string, object>
con el método Clear
después de que una página lo reciba por primera vez.
Pasar datos de navegación basados en objetos de uso único
Los datos de navegación basados en objetos de uso único se pueden pasar con una sobrecarga de GoToAsync que especifica un argumento ShellNavigationQueryParameters. El objeto ShellNavigationQueryParameters está diseñado para datos de navegación de uso único que se borran después de que se haya producido la navegación. En el ejemplo siguiente se muestra cómo navegar mientras se pasan datos de uso único:
async void OnCollectionViewSelectionChanged(object sender, SelectionChangedEventArgs e)
{
Animal animal = e.CurrentSelection.FirstOrDefault() as Animal;
var navigationParameter = new ShellNavigationQueryParameters
{
{ "Bear", animal }
};
await Shell.Current.GoToAsync($"beardetails", navigationParameter);
}
En este ejemplo se recupera el oso seleccionado actualmente en CollectionView, como Animal
que se agrega al objeto ShellNavigationQueryParameters. A continuación, se realiza la navegación a la ruta beardetails
, con el objeto ShellNavigationQueryParameters que se pasa como parámetro de navegación. Después de que se haya producido la navegación, se borran los datos del objeto ShellNavigationQueryParameters.
Recepción de datos de navegación
Hay dos formas de recibir datos de navegación:
- La clase que representa la página a la que se navega, o la clase correspondiente al objeto
BindingContext
de la página, se puede decorar con un elemento QueryPropertyAttribute por cada parámetro de consulta. Para obtener más información, vea Procesamiento de datos de navegación mediante atributos de propiedad de consulta. - La clase que representa la página a la que se navega, o la clase correspondiente al objeto
BindingContext
de la página, puede implementar la interfaz IQueryAttributable. Para obtener más información, vea Procesamiento de datos de navegación mediante un único método.
Procesamiento de datos de navegación mediante atributos de propiedad de consulta
Para recibir datos de navegación, se puede decorar la clase receptora con QueryPropertyAttribute para cada parámetro de consulta basado en cadenas y cada parámetro de navegación basado en objetos o el objeto ShellNavigationQueryParameters:
[QueryProperty(nameof(Bear), "Bear")]
public partial class BearDetailPage : ContentPage
{
Animal bear;
public Animal Bear
{
get => bear;
set
{
bear = value;
OnPropertyChanged();
}
}
public BearDetailPage()
{
InitializeComponent();
BindingContext = this;
}
}
En este ejemplo, el primer argumento de QueryPropertyAttribute especifica el nombre de la propiedad que recibirá los datos, mientras que el segundo argumento especifica el identificador del parámetro de consulta. Por lo tanto, QueryPropertyAttribute del ejemplo anterior especifica que la propiedad Bear
recibirá los datos pasados al parámetro de navegación Bear
en la llamada al método GoToAsync.
Importante
Los valores de los parámetros de consulta basados en cadenas que se reciben a través de QueryPropertyAttribute se descodifican automáticamente en la URL.
Advertencia
La recepción de datos de navegación mediante QueryPropertyAttribute no es segura y no debe usarse con recorte completo ni NativeAOT. En su lugar, debe implementar la IQueryAttributable interfaz en los tipos que necesitan aceptar parámetros de consulta. Para obtener más información, consulte Procesamiento de datos de navegación mediante un único método, Recorte de una aplicación MAUI de .NET y implementación de AOT nativa.
Procesamiento de datos de navegación mediante un único método
Para recibir datos de navegación, se puede implementar la interfaz IQueryAttributable en la clase receptora. La interfaz IQueryAttributable especifica que la clase encargada de la implementación debe implementar el método ApplyQueryAttributes
. Este método tiene un argumento query
, de tipo IDictionary<string, object>
, que contiene los datos que se pasan durante la navegación. Cada clave del diccionario es un identificador de parámetro de consulta, con su valor correspondiente al objeto que representa los datos. La ventaja de usar este método es que los datos de navegación se pueden procesar con un único método, lo que puede resultar útil cuando hay varios elementos de datos de navegación que deben procesarse como un todo.
En el siguiente ejemplo se muestra una clase de modelo de vista que implementa la interfaz IQueryAttributable:
public class MonkeyDetailViewModel : IQueryAttributable, INotifyPropertyChanged
{
public Animal Monkey { get; private set; }
public void ApplyQueryAttributes(IDictionary<string, object> query)
{
Monkey = query["Monkey"] as Animal;
OnPropertyChanged("Monkey");
}
...
}
En este ejemplo, el método ApplyQueryAttributes
recupera el objeto que corresponde a la clave Monkey
del diccionario query
, que se pasó como argumento a la llamada al método GoToAsync.
Importante
Los valores de parámetros de consulta basados en cadenas que se reciben a través de la interfaz IQueryAttributable no se descodifican automáticamente como dirección URL.
Pasar y procesar varios elementos de datos
Se pueden pasar varios parámetros de consulta basados en cadenas conectándolos con &
. Por ejemplo, el código siguiente pasa dos elementos de datos:
async void OnCollectionViewSelectionChanged(object sender, SelectionChangedEventArgs e)
{
string elephantName = (e.CurrentSelection.FirstOrDefault() as Animal).Name;
string elephantLocation = (e.CurrentSelection.FirstOrDefault() as Animal).Location;
await Shell.Current.GoToAsync($"elephantdetails?name={elephantName}&location={elephantLocation}");
}
En este ejemplo de código se recupera el elefante actualmente seleccionado en CollectionView y se navega a la ruta elephantdetails
; además, se pasan elephantName
y elephantLocation
como parámetros de consulta.
Para recibir varios elementos de datos, la clase que representa la página a la que se navega, o la clase para BindingContext
de la página, se puede decorar con QueryPropertyAttribute por cada parámetro de consulta basado en cadenas:
[QueryProperty(nameof(Name), "name")]
[QueryProperty(nameof(Location), "location")]
public partial class ElephantDetailPage : ContentPage
{
public string Name
{
set
{
// Custom logic
}
}
public string Location
{
set
{
// Custom logic
}
}
...
}
En este ejemplo, la clase se decora con un objeto QueryPropertyAttribute para cada parámetro de consulta. El primer objeto QueryPropertyAttribute especifica que la propiedad Name
recibirá los datos pasados en el parámetro de consulta name
, mientras que el segundo objeto QueryPropertyAttribute especifica que la propiedad Location
recibirá los datos pasado en el parámetro de consulta location
. En ambos casos, los valores de los parámetros de consulta se especifican en el URI en la llamada al método GoToAsync.
Advertencia
La recepción de datos de navegación mediante QueryPropertyAttribute no es segura y no debe usarse con recorte completo ni NativeAOT. En su lugar, debe implementar la IQueryAttributable interfaz en los tipos que necesitan aceptar parámetros de consulta. Para obtener más información, consulte Recorte de una aplicación MAUI de .NET y implementación de AOT nativa.
Opcionalmente, para procesar datos de navegación mediante un único método, se puede implementar la interfaz IQueryAttributable en la clase que representa la página a la que se navega, o la clase correspondiente al objeto BindingContext
de la página:
public class ElephantDetailViewModel : IQueryAttributable, INotifyPropertyChanged
{
public Animal Elephant { get; private set; }
public void ApplyQueryAttributes(IDictionary<string, object> query)
{
string name = HttpUtility.UrlDecode(query["name"].ToString());
string location = HttpUtility.UrlDecode(query["location"].ToString());
...
}
...
}
En este ejemplo, el método ApplyQueryAttributes
recupera el valor de los parámetros de consulta name
y location
del URI incluido en la llamada de método GoToAsync.
Nota:
Los parámetros de consulta basados en cadenas y los parámetros de navegación basados en objetos se pueden pasar simultáneamente al realizar la navegación basada en rutas.
Comportamiento del botón Atrás
La apariencia y el comportamiento del botón Atrás se pueden volver a definir estableciendo la propiedad adjunta BackButtonBehavior en un objeto BackButtonBehavior. La clase BackButtonBehavior define las propiedades siguientes:
Command
, de tipo ICommand, que se ejecuta cuando se presiona el botón Atrás.CommandParameter
, de tipoobject
, que es el parámetro que se pasa al objetoCommand
.IconOverride
, de tipo ImageSource, el icono usado para el botón Atrás.IsEnabled
, de tipoboolean
, indica si se ha habilitado el botón Atrás. El valor predeterminado estrue
.IsVisible
, de tipoboolean
, indica si el botón Atrás está visible. El valor predeterminado estrue
.TextOverride
, de tipostring
, el texto usado para el botón Atrás.
Todas estas propiedades están respaldados por objetos BindableProperty, lo que significa que las propiedades pueden ser destinos de los enlaces de datos. Cada BindableProperty tiene un modo de enlace OneTime
, lo que significa que los datos van del origen al destino pero solo cuando cambia BindingContext
.
Todas estas propiedades están respaldados por objetos BindableProperty, lo que significa que las propiedades pueden ser destinos de los enlaces de datos. Los objetos Command
, CommandParameter
, IconOveride
y TextOveride
BindableProperty tienen modos de enlace OneTime
, lo que significa que los datos van del origen al destino pero solo cuando cambia BindingContext
. Los objetos IsEnabled
y IsVisible
BindableProperty tienen modos de enlace OneWay
, lo que significa que los datos van del origen al destino.
En el código siguiente se muestra un ejemplo de cómo volver a definir la apariencia y el comportamiento del botón Atrás:
<ContentPage ...>
<Shell.BackButtonBehavior>
<BackButtonBehavior Command="{Binding BackCommand}"
IconOverride="back.png" />
</Shell.BackButtonBehavior>
...
</ContentPage>
La propiedad Command
se establece en ICommand para ejecutarse cuando se presiona el botón Atrás y la propiedad IconOverride
se establece en el icono que se usa para el botón Atrás: