Condividi tramite


Spostamento della shell di .NET MAUI

Sfogliare l'esempio. Esplorare l'esempio

La shell .NET Multi-platform App UI (.NET MAUI) include un'esperienza di spostamento basata su URI che usa le route per spostarsi su qualsiasi pagina dell'app, senza che sia necessario seguire una gerarchia di spostamento definita. La shell offre anche la possibilità di spostarsi all'indietro senza dover visitare tutte le pagine dello stack di spostamento.

La Shell classe definisce le proprietà correlate allo spostamento seguenti:

  • BackButtonBehavior, di tipo BackButtonBehavior, una proprietà associata che definisce il comportamento del pulsante Indietro.
  • CurrentItem, di tipo ShellItem, l'elemento attualmente selezionato.
  • CurrentPage, di tipo Page, la pagina attualmente presentata.
  • CurrentState, di tipo ShellNavigationState, lo stato di spostamento corrente di Shell.
  • Current, di tipo Shell, un alias con cast del tipo per Application.Current.MainPage.

Le proprietà BackButtonBehavior, CurrentItem e CurrentState sono supportate da oggetti BindableProperty e ciò significa che tali proprietà possono essere destinazioni di data binding.

Lo spostamento viene eseguito richiamando il metodo GoToAsync dalla classe Shell. Quando lo spostamento sta per essere eseguito, viene generato l'evento Navigating e l'evento Navigated viene generato al termine della navigazione.

Nota

Lo spostamento può comunque essere eseguito tra le pagine di un'app Shell usando la Navigation proprietà . Per altre informazioni, vedere Eseguire lo spostamento senza modalità.

Route

Lo spostamento viene eseguito in un'app Shell specificando un URI a cui passare. Gli URL di spostamento possono essere composti da tre componenti:

  • Una route, che definisce il percorso del contenuto esistente nell'ambito della gerarchia visiva di Shell.
  • Una pagina. Le pagine che non esistono nella gerarchia visiva di Shell possono essere inserite nello stack di spostamento da qualsiasi posizione all'interno di un'app Shell. Una pagina dei dettagli, ad esempio, non viene definita nella gerarchia visiva di Shell, ma può essere inserita nello stack di spostamento in base alle esigenze.
  • Uno o più parametri di query. I parametri di query possono essere passati alla pagina di destinazione durante lo spostamento.

Quando un URI di spostamento include tutti i componenti, la struttura è la seguente: //route/page?queryParameters

Registrare le route

Le route possono essere definite in FlyoutItemoggetti , TabBarTab, e ShellContent tramite le relative Route proprietà:

<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

A tutti gli elementi nella gerarchia della shell è associata una route. Se non si imposta una route, ne viene generata una in fase di esecuzione. Tuttavia, le route generate non sono sicuramente coerenti tra diverse sessioni dell'app.

L'esempio precedente crea la gerarchia di route seguente, che può essere usata nella struttura di spostamento a livello di codice:

animals
  domestic
    cats
    dogs
  monkeys
  elephants
  bears
about

Per passare all'oggetto ShellContent per la route dogs, l'URI della route assoluto è //animals/domestic/dogs. Analogamente, per passare all'oggetto ShellContent per la route about, l'URI della route assoluto è //about.

Avviso

Verrà generata un'eccezione ArgumentException all'avvio dell'app se viene rilevata una route duplicata. Questa eccezione viene generata anche se due o più route allo stesso livello nella gerarchia condividono un nome di route.

Registrare le route della pagina dei dettagli

Nel costruttore della sottoclasse Shell o in qualsiasi altra posizione eseguita prima di richiamare una route, è possibile registrare in modo esplicito route aggiuntive per tutte le pagine di dettaglio non rappresentate nella gerarchia visiva di Shell. Questa operazione viene eseguita con il metodo 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));

In questo esempio vengono registrate le pagine di dettaglio, non definite nella Shell sottoclasse, come route. È quindi possibile passare a queste pagine di dettaglio usando lo spostamento basato su URI, da qualsiasi posizione all'interno dell'app. Le route per queste pagine sono dette route globali.

Avviso

Viene generata un'eccezione ArgumentException se il metodo Routing.RegisterRoute tenta di registrare la stessa route a due o più tipi diversi.

In alternativa, le pagine possono essere registrate in gerarchie di route diverse, se necessario:

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));

Questo esempio abilita la navigazione contestuale tra le pagine, con la quale se si passa alla route details dalla pagina relativa a monkeys viene visualizzato l'oggetto MonkeyDetailPage. Analogamente, se si passa alla route details dalla pagina relativa a elephants viene visualizzato l'oggetto ElephantDetailPage. Per altre informazioni, vedere Navigazione contestuale.

Nota

Per le pagine le cui route sono state registrate con il metodo Routing.RegisterRoute, è possibile annullare la registrazione con il metodo Routing.UnRegisterRoute, se necessario.

Eseguire la navigazione

Per eseguire la navigazione, è prima necessario ottenere un riferimento alla sottoclasse Shell. Questo riferimento può essere ottenuto eseguendo il cast della proprietà App.Current.MainPage in un oggetto Shell oppure tramite la proprietà Shell.Current. La navigazione può quindi essere eseguita chiamando il metodo GoToAsync nell'oggetto Shell. Questo metodo consente di passare a ShellNavigationState e restituisce un oggetto Task che verrà completato al termine dell'animazione relativa alla navigazione. L'oggetto ShellNavigationState viene costruito dal metodo GoToAsync, da un oggetto string o da un oggetto Uri e la sua proprietà Location è impostata sull'argomento string o Uri.

Importante

Quando si passa a una route dalla gerarchia visiva della shell, non viene creato uno stack di navigazione. Tuttavia, quando si passa a una pagina non presente nella gerarchia visiva della shell, lo stack di navigazione viene creato.

Lo stato di navigazione corrente dell'oggetto Shell può essere recuperato tramite la Shell.Current.CurrentState proprietà , che include l'URI della route visualizzata nella Location proprietà .

Route assolute

La navigazione può essere eseguita specificando un URI assoluto valido come argomento del metodo GoToAsync:

await Shell.Current.GoToAsync("//animals/monkeys");

Questo esempio consente di passare alla pagina per la route monkeys, con la route definita in un oggetto ShellContent. L'oggetto ShellContent che rappresenta la route monkeys è figlio di un oggetto FlyoutItem, la cui route è animals.

Route relative

La navigazione può essere eseguita anche specificando un URI relativo valido come argomento del metodo GoToAsync. Il sistema di routing cercherà di trovare una corrispondenza tra l'URI e un oggetto ShellContent. Pertanto, se tutte le route in un'app sono univoche, la navigazione può essere eseguita specificando solo il nome di route univoco come URI relativo.

Sono supportati i formati di route relativi seguenti:

Formato Descrizione
route La gerarchia di route verrà cercata per la route specificata, verso l'alto dalla posizione corrente. Verrà eseguito il push della pagina corrispondente nello stack di navigazione.
/route La gerarchia di route verrà eseguita dalla route specificata, verso il basso dalla posizione corrente. Verrà eseguito il push della pagina corrispondente nello stack di navigazione.
//route La gerarchia di route verrà cercata per la route specificata, verso l'alto dalla posizione corrente. La pagina corrispondente sostituirà lo stack di navigazione.
///route La gerarchia di route verrà cercata per la route specificata, verso il basso dalla posizione corrente. La pagina corrispondente sostituirà lo stack di navigazione.

Nell'esempio seguente viene visualizzata la pagina per la monkeydetails route:

await Shell.Current.GoToAsync("monkeydetails");

In questo esempio viene eseguita la ricerca della monkeyDetails route fino a quando non viene trovata la pagina corrispondente. Quando viene trovata la pagina, viene eseguito il push nello stack di navigazione.

Navigazione contestuale

Le route relative consentono la navigazione contestuale. Si consideri ad esempio la gerarchia di route seguente:

monkeys
  details
bears
  details

Quando è visualizzata la pagina registrata per la route monkeys, se si passa alla route details viene visualizzata la pagina registrata per la route monkeys/details. Analogamente, quando è visualizzata la pagina registrata per la route bears, se si passa alla route details viene visualizzata la pagina registrata per la route bears/details. Per informazioni su come registrare le route in questo esempio, vedere Registrare le route di pagine.

Spostamento indietro

Per eseguire lo spostamento indietro, è possibile specificare ".." come argomento al metodo GoToAsync:

await Shell.Current.GoToAsync("..");

La navigazione all'indietro con ".." può anche essere combinata con un itinerario:

await Shell.Current.GoToAsync("../route");

In questo esempio viene eseguita la navigazione all'indietro e quindi si passa alla route specificata.

Importante

Spostarsi all'indietro e in una route specificata è possibile solo se lo spostamento all'indietro si trova nella posizione corrente nella gerarchia di route per passare alla route specificata.

Analogamente, è possibile spostarsi più volte all'indietro e quindi passare a una route specificata:

await Shell.Current.GoToAsync("../../route");

In questo esempio la navigazione all'indietro viene eseguita due volte e quindi si passa alla route specificata.

Inoltre, i dati possono essere passati tramite proprietà di query durante lo spostamento all'indietro:

await Shell.Current.GoToAsync($"..?parameterToPassBack={parameterValueToPassBack}");

In questo esempio viene eseguita la navigazione all'indietro e il valore del parametro di query viene passato al parametro di query nella pagina precedente.

Nota

I parametri di query possono essere aggiunti a qualsiasi richiesta di navigazione all'indietro.

Per altre informazioni sul passaggio dei dati durante l'esplorazione, vedere Passare i dati.

Route non valide

I formati di route seguenti non sono validi:

Formato Spiegazione
//page o ///page Le route globali attualmente non possono essere l'unica pagina nello stack di navigazione. Il routing assoluto per le route globali non è quindi supportato.

L'uso di questi formati di route comporta la visualizzazione di un'eccezione Exception .

Avviso

Un tentativo di passare a una route non esistente causa la generazione di un'eccezione ArgumentException.

Debug della navigazione

Alcune classi della shell sono decorate con DebuggerDisplayAttribute, che specifica in che modo il debugger visualizza una classe o un campo. Ciò può essere utile per eseguire il debug delle richieste di navigazione visualizzando i dati correlati alla richiesta di navigazione. Lo screenshot seguente mostra ad esempio le proprietà CurrentItem e CurrentState dell'oggetto Shell.Current:

Screenshot del debugger.

In questo esempio la proprietà CurrentItem, di tipo FlyoutItem, visualizza il titolo e la route dell'oggetto FlyoutItem. Analogamente, la CurrentState proprietà di tipo ShellNavigationState, visualizza l'URI della route visualizzata all'interno dell'app Shell.

La Tab classe definisce una Stack proprietà di tipo IReadOnlyList<Page>, che rappresenta lo stack di navigazione corrente all'interno di Tab. La classe fornisce anche i metodi di spostamento sostituibili seguenti:

  • GetNavigationStack, restituisce IReadOnlyList<Page>, lo stack di navigazione corrente.
  • OnInsertPageBefore, chiamato quando si chiama INavigation.InsertPageBefore.
  • OnPopAsync, restituisce Task<Page> e viene chiamato quando si chiama INavigation.PopAsync.
  • OnPopToRootAsync, restituisce Task e viene chiamato quando si chiama INavigation.OnPopToRootAsync.
  • OnPushAsync, restituisce Task e viene chiamato quando si chiama INavigation.PushAsync.
  • OnRemovePage, chiamato quando si chiama INavigation.RemovePage.

Nell'esempio seguente viene illustrato come eseguire l'override del OnRemovePage metodo :

public class MyTab : Tab
{
    protected override void OnRemovePage(Page page)
    {
        base.OnRemovePage(page);

        // Custom logic
    }
}

In questo esempio, MyTab gli oggetti devono essere utilizzati nella gerarchia visiva della shell anziché negli Tab oggetti .

La Shell classe definisce l'evento Navigating , che viene generato quando lo spostamento sta per essere eseguito, a causa della navigazione a livello di codice o dell'interazione dell'utente. L'oggetto ShellNavigatingEventArgs che accompagna l'evento Navigating fornisce le proprietà seguenti:

Proprietà Type Descrizione
Current ShellNavigationState URI della pagina corrente.
Source ShellNavigationSource Tipo di navigazione eseguita.
Target ShellNavigationState URI che rappresenta la destinazione della navigazione.
CanCancel bool Valore che indica se è possibile annullare la navigazione.
Cancelled bool Valore che indica se la navigazione è stata annullata.

Inoltre, la ShellNavigatingEventArgs classe fornisce un Cancel metodo che può essere usato per annullare la navigazione e un GetDeferral metodo che restituisce un ShellNavigatingDeferral token che può essere usato per completare la navigazione. Per altre informazioni sul rinvio dello spostamento, vedere Rinvio della navigazione.

La Shell classe definisce anche l'evento Navigated , che viene generato al termine della navigazione. L'oggetto ShellNavigatedEventArgs che accompagna l'evento Navigated fornisce le proprietà seguenti:

Proprietà Type Descrizione
Current ShellNavigationState URI della pagina corrente.
Previous ShellNavigationState URI della pagina precedente.
Source ShellNavigationSource Tipo di navigazione eseguita.

Importante

Il OnNavigating metodo viene chiamato quando viene generato l'evento Navigating . Analogamente, il OnNavigated metodo viene chiamato quando viene generato l'evento Navigated . Entrambi i metodi possono essere sottoposti a override nella Shell sottoclasse per intercettare le richieste di navigazione.

Le classi ShellNavigatedEventArgs e ShellNavigatingEventArgs hanno entrambe proprietà Source, di tipo ShellNavigationSource. Questa enumerazione fornisce i valori seguenti:

  • Unknown
  • Push
  • Pop
  • PopToRoot
  • Insert
  • Remove
  • ShellItemChanged
  • ShellSectionChanged
  • ShellContentChanged

Pertanto, la navigazione può essere intercettata in un OnNavigating override e le azioni possono essere eseguite in base all'origine di navigazione. Il codice seguente illustra ad esempio come annullare la navigazione indietro se i dati nella pagina non sono stati salvati:

protected override void OnNavigating(ShellNavigatingEventArgs args)
{
    base.OnNavigating(args);

    // Cancel any back navigation.
    if (args.Source == ShellNavigationSource.Pop)
    {
        args.Cancel();
    }
}

Lo spostamento della shell può essere intercettato e completato o annullato in base alla scelta dell'utente. A tale scopo, è possibile eseguire l'override del OnNavigating metodo nella Shell sottoclasse e chiamando il GetDeferral metodo sull'oggetto ShellNavigatingEventArgs . Questo metodo restituisce un ShellNavigatingDeferral token con un Complete metodo, che può essere usato per completare la richiesta di navigazione:

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();
    }    
}

In questo esempio viene visualizzata una finestra delle azioni che invita l'utente a completare la richiesta di navigazione o annullarla. La navigazione viene annullata richiamando il Cancel metodo sull'oggetto ShellNavigatingEventArgs . La navigazione viene completata richiamando il Complete metodo sul ShellNavigatingDeferral token recuperato dal GetDeferral metodo sull'oggetto ShellNavigatingEventArgs .

Avviso

Il GoToAsync metodo genererà un'eccezione InvalidOperationException se un utente tenta di spostarsi mentre è presente un differire di navigazione in sospeso.

Passare dati

I dati primitivi possono essere passati come parametri di query basati su stringa quando si esegue lo spostamento programmatico basato su URI. Ciò si ottiene accodando ? dopo una route, seguita da un ID parametro di query, =, e un valore:

async void OnCollectionViewSelectionChanged(object sender, SelectionChangedEventArgs e)
{
    string elephantName = (e.CurrentSelection.FirstOrDefault() as Animal).Name;
    await Shell.Current.GoToAsync($"elephantdetails?name={elephantName}");
}

In questo esempio viene recuperato l'elefante attualmente selezionato in CollectionViewe si passa alla elephantdetails route passando elephantName come parametro di query.

Passare più dati di navigazione basati su oggetti

È possibile passare più dati di navigazione basati su oggetti con un GoToAsync overload che specifica un IDictionary<string, object> argomento:

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);
}

In questo esempio viene recuperato l'orso attualmente selezionato in CollectionView, come Animal. L'oggetto Animal viene aggiunto a un Dictionary oggetto con la chiave Bear. Viene quindi eseguita la navigazione sulla beardetails route, con l'oggetto Dictionary passato come parametro di navigazione.

Tutti i dati passati come IDictionary<string, object> argomento vengono conservati in memoria per la durata della pagina e non vengono rilasciati finché la pagina non viene rimossa dallo stack di navigazione. Questo può essere problematico, come illustrato nello scenario seguente:

  1. Page1 passa a Page2 usando il GoToAsync metodo , passando un oggetto denominato MyData. Page2 riceve MyData quindi come parametro di query.
  2. Page2 passa all'uso Page3 del GoToAsync metodo , senza passare dati.
  3. Page3 si sposta all'indietro con il GoToAsync metodo . Page2 quindi riceve MyData nuovamente come parametro di query.

Anche se questo è auspicabile in molti scenari, se non si vuole cancellare l'argomento IDictionary<string, object> con il Clear metodo dopo che è stato ricevuto per la prima volta da una pagina.

Passare i dati di spostamento basati su oggetti singolo

I dati di spostamento basati su oggetti possono essere passati con un GoToAsync overload che specifica un ShellNavigationQueryParameters argomento. Un ShellNavigationQueryParameters oggetto è destinato ai dati di navigazione a uso singolo che vengono cancellati dopo che si è verificato lo spostamento. L'esempio seguente illustra l'esplorazione durante il passaggio di dati a uso singolo:

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);
}

In questo esempio viene recuperato l'orso attualmente selezionato in CollectionView, come oggetto Animal aggiunto all'oggetto ShellNavigationQueryParameters . Viene quindi eseguita la navigazione sulla beardetails route, con l'oggetto ShellNavigationQueryParameters passato come parametro di navigazione. Dopo che la navigazione è stata eseguita, i dati nell'oggetto ShellNavigationQueryParameters sono stati cancellati.

Ricevere i dati di navigazione

Esistono due approcci per ricevere i dati di navigazione:

  1. La classe che rappresenta la pagina a cui si passa oppure la classe per la pagina può BindingContextessere decorata con un QueryPropertyAttribute oggetto per ogni parametro di query. Per altre informazioni, vedere Elaborare i dati di navigazione usando gli attributi delle proprietà di query.
  2. La classe che rappresenta la pagina a cui si passa o la classe per la pagina può BindingContextimplementare l'interfaccia IQueryAttributable . Per altre informazioni, vedere Elaborare i dati di navigazione usando un singolo metodo.

Elaborare i dati di navigazione usando gli attributi delle proprietà di query

I dati di navigazione possono essere ricevuti decorando la classe ricevente con un QueryPropertyAttribute oggetto per ogni parametro di query basato su stringa, parametro di navigazione basato su oggetti o ShellNavigationQueryParameters oggetto:

[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;
    }
}

In questo esempio il primo argomento per l'oggetto QueryPropertyAttribute specifica il nome della proprietà che riceverà i dati, con il secondo argomento che specifica l'ID parametro. Pertanto, QueryPropertyAttribute nell'esempio precedente viene specificato che la Bear proprietà riceverà i dati passati nel Bear parametro di navigazione nella chiamata al GoToAsync metodo.

Importante

I valori dei parametri di query basati su stringhe ricevuti tramite QueryPropertyAttribute vengono decodificati automaticamente tramite URL.

Avviso

La ricezione dei dati di navigazione tramite QueryPropertyAttribute non è sicura e non deve essere usata con taglio completo o NativeAOT. È invece necessario implementare l'interfaccia IQueryAttributable sui tipi che devono accettare parametri di query. Per altre informazioni, vedere Elaborare i dati di spostamento usando un singolo metodo, Trim a .NET MAUI app e Distribuzione nativa di AOT.

Elaborare i dati di navigazione usando un singolo metodo

I dati di navigazione possono essere ricevuti implementando l'interfaccia IQueryAttributable nella classe ricevente. L'interfaccia IQueryAttributable specifica che la classe di implementazione deve implementare il ApplyQueryAttributes metodo . Questo metodo ha un query argomento di tipo IDictionary<string, object>, che contiene tutti i dati passati durante la navigazione. Ogni chiave nel dizionario è un ID parametro di query, con il relativo valore corrispondente all'oggetto che rappresenta i dati. Il vantaggio di usare questo approccio è che i dati di navigazione possono essere elaborati usando un unico metodo, che può essere utile quando si dispone di più elementi di dati di navigazione che richiedono l'elaborazione nel suo complesso.

L'esempio seguente mostra una classe del modello di visualizzazione che implementa l'interfaccia 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");
    }
    ...
}

In questo esempio, il ApplyQueryAttributes metodo recupera l'oggetto che corrisponde alla Monkey chiave nel query dizionario, che è stato passato come argomento alla chiamata al GoToAsync metodo.

Importante

I valori dei parametri di query basati su stringhe ricevuti tramite l'interfaccia non vengono decodificati automaticamente nell'URL IQueryAttributable .

Passare ed elaborare più elementi di dati

È possibile passare più parametri di query basati su stringhe collegandoli con &. Ad esempio, il codice seguente passa due elementi di dati:

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}");
}

Questo esempio di codice recupera l'elefante attualmente selezionato in CollectionViewe passa alla elephantdetails route, passando elephantName e elephantLocation come parametri di query.

Per ricevere più elementi di dati, la classe che rappresenta la pagina a cui si passa o la classe per la pagina può BindingContextessere decorata con un QueryPropertyAttribute per ogni parametro di query basato su stringa:

[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
        }
    }
    ...    
}

In questo esempio la classe è decorata con un QueryPropertyAttribute oggetto per ogni parametro di query. Il primo QueryPropertyAttribute specifica che la Name proprietà riceverà i dati passati nel name parametro di query, mentre il secondo QueryPropertyAttribute specifica che la Location proprietà riceverà i dati passati nel location parametro di query. In entrambi i casi, i valori dei parametri di query vengono specificati nell'URI nella chiamata al GoToAsync metodo.

Avviso

La ricezione dei dati di navigazione tramite QueryPropertyAttribute non è sicura e non deve essere usata con taglio completo o NativeAOT. È invece necessario implementare l'interfaccia IQueryAttributable sui tipi che devono accettare parametri di query. Per altre informazioni, vedere Trim a .NET MAUI app and Native AOT deployment (Trim a .NET MAUI app and Native AOT deployment).

In alternativa, i dati di navigazione possono essere elaborati da un singolo metodo implementando l'interfaccia IQueryAttributable nella classe che rappresenta la pagina a cui si passa o la classe per la pagina della BindingContextpagina :

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());
        ...        
    }
    ...
}

In questo esempio, il ApplyQueryAttributes metodo recupera il valore dei parametri di name query e location dall'URI nella chiamata al GoToAsync metodo.

Nota

È possibile passare contemporaneamente parametri di query basati su stringhe e parametri di spostamento basati su oggetti durante l'esecuzione dello spostamento basato su route.

Comportamento del pulsante Indietro

È possibile ridefinire l'aspetto e il comportamento del pulsante Indietro impostando la BackButtonBehavior proprietà associata su un BackButtonBehavior oggetto . La BackButtonBehavior classe definisce le proprietà seguenti:

  • Command, di tipo ICommand. Questo oggetto viene eseguito quando si preme sul pulsante Indietro.
  • CommandParameter, di tipo object, ovvero il parametro passato a Command.
  • IconOverride, di tipo ImageSource, ovvero l'icona usata per il pulsante Indietro.
  • IsEnabled, di tipo boolean, che indica se il pulsante Indietro è abilitato. Il valore predefinito è true.
  • IsVisible, di tipo boolean, indica se il pulsante Indietro è visibile. Il valore predefinito è true.
  • TextOverride, di tipo string, ovvero il testo usato per il pulsante Indietro.

Tutte queste proprietà sono supportate da oggetti BindableProperty e ciò significa che tali proprietà possono essere destinazioni di data binding. Ogni BindableProperty oggetto ha una OneTime modalità di associazione, il che significa che i dati passano dall'origine alla destinazione, ma solo quando cambiano BindingContext .

Tutte queste proprietà sono supportate da oggetti BindableProperty e ciò significa che tali proprietà possono essere destinazioni di data binding. Gli Commandoggetti , IconOverideCommandParameter, e TextOveride BindableProperty hanno OneTime modalità di associazione, il che significa che i dati passano dall'origine alla destinazione, ma solo quando vengono BindingContext modificati. Gli IsEnabled oggetti e IsVisible BindableProperty hanno OneWay modalità di associazione, il che significa che i dati passano dall'origine alla destinazione.

Il codice seguente mostra un esempio di ridefinizione dell'aspetto e del comportamento del pulsante Indietro:

<ContentPage ...>    
    <Shell.BackButtonBehavior>
        <BackButtonBehavior Command="{Binding BackCommand}"
                            IconOverride="back.png" />   
    </Shell.BackButtonBehavior>
    ...
</ContentPage>

La proprietà Command è impostata su un oggetto ICommand da eseguire quando si preme il pulsante Indietro, mentre la proprietà IconOverride è impostata sull'icona usata per il pulsante Indietro:

Screenshot dell'override dell'icona del pulsante Indietro della shell.