Teilen über


.NET MAUI Shell-Navigation

Beispiel durchsuchen.Durchsuchen Sie das Beispiel

.NET Multi-Platform App UI(.NET MAUI)-Shell enthält eine URI-basierte Navigationsoberfläche, die Routen verwendet, um zu einer beliebigen Seite in der App zu navigieren, ohne einer festgelegten Navigationshierarchie folgen zu müssen. Darüber hinaus bietet es auch die Möglichkeit, rückwärts zu navigieren, ohne alle Seiten des Navigationsstapels aufrufen zu müssen.

In der Shell-Klasse sind die folgenden Navigationseigenschaften definiert:

  • BackButtonBehavior vom Typ BackButtonBehavior: eine angefügte Eigenschaft, die das Verhalten der Zurück-Schaltfläche definiert.
  • CurrentItem, vom Typ ShellItem: Das aktuell ausgewählte Element
  • CurrentPage, vom Typ Page: die aktuell dargestellte Seite.
  • CurrentState vom Typ ShellNavigationState: der aktuelle Navigationszustand der Shell.
  • Current, vom Typ Shell, der Zugriff auf die aktuelle Shell ermöglicht.

Die Eigenschaften BackButtonBehavior, CurrentItem und CurrentState werden durch BindableProperty-Objekte gestützt, was bedeutet, dass diese Eigenschaften Ziele von Datenverbindungen sein können.

Navigation erfolgt durch Aufrufen der GoToAsync-Methode aus der Shell-Klasse. Kurz bevor die Navigation erfolgt, wird ein Navigating-Ereignis ausgelöst, und das Navigated-Ereignis wird ausgelöst, wenn die Navigation abgeschlossen ist.

Hinweis

Die Navigation zwischen den Seiten in einer Shell-App kann weiterhin mit der Eigenschaft Navigation erfolgen. Weitere Informationen finden Sie unter Navigation ohne Modus durchführen.

Routen

Die Navigation erfolgt in einer Shell-App durch Angabe eines URI, zu dem navigiert werden soll. Navigation-URIs können drei Komponenten aufweisen:

  • Eine Route, die den Pfad zu Inhalt definiert, der als Teil der visuellen Shell-Hierarchie vorhanden ist.
  • Eine Seite. Seiten, die in der visuellen Hierarchie der Shell nicht vorhanden sind, können von praktisch überall in einer Shell-App in den Navigationsstapel verschoben werden. Beispielsweise wird eine Detailseite nicht in der visuellen Shellhierarchie definiert, sondern kann bei Bedarf mithilfe von Push an den Navigationsstapel übertragen werden.
  • Mindestens ein Abfrageparameter. Abfrageparameter sind Parameter, die während der Navigation an die Zielseite übergeben werden können.

Wenn ein Navigations-URI alle drei Komponenten enthält, lautet die Struktur „//route/page?queryParameters“.

Registrieren von Routen

Routen können für FlyoutItem-, TabBar-, Tab- und ShellContent-Objekte über ihre Route-Eigenschaften definiert werden:

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

Hinweis

Allen Elementen in der Shell-Hierarchie ist eine Route zugeordnet. Wenn Sie keine Route festlegen, wird zur Laufzeit eine generiert. Es ist jedoch nicht gewährleistet, dass die generierten Routen über verschiedene App-Sitzungen hinweg konsistent sind.

Im obigen Beispiel wird die folgende Routenhierarchie erstellt, die bei der programmgesteuerten Navigation verwendet werden kann:

animals
  domestic
    cats
    dogs
  monkeys
  elephants
  bears
about

Der absolute Routen-URI lautet //animals/domestic/dogs, um zum ShellContent-Objekt für die dogs-Route zu navigieren. Um zum ShellContent-Objekt für die about-Route zu navigieren, lautet der absolute Routen-URI entsprechend //about.

Warnung

ArgumentException wird beim Start der App ausgelöst, wenn eine doppelte Route entdeckt wird. Diese Ausnahme wird auch ausgelöst, wenn mindestens zwei Routen auf derselben Ebene in der Hierarchie einen Routennamen gemeinsam verwenden.

Registrieren von Detailseitenrouten

Im Shell-Unterklassenkonstruktor oder an jedem anderen Ort, der vor dem Aufruf einer Route ausgeführt wird, können zusätzliche Routen explizit für alle Detailseiten registriert werden, die in der visuellen Shellhierarchie nicht repräsentiert werden. Dies wird mit der Routing.RegisterRoute-Methode erreicht:

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 diesem Beispiel werden Detailseiten, die nicht in der Shell-Unterklasse definiert sind, als Routen registriert. Diese Detailseiten können dann über eine URI-basierte Navigation von überall in der App aus angesteuert werden. Die Routen für solche Seiten werden als globale Routen bezeichnet.

Warnung

Eine ArgumentException wird ausgelöst, wenn die Routing.RegisterRoute-Methode versucht, dieselbe Route für mindestens zwei unterschiedliche Typen zu registrieren.

Alternativ können Seiten bei Bedarf bei verschiedenen Routenhierarchien registriert werden:

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

Dieses Beispiel ermöglicht eine kontextbezogene Seitennavigation, bei der die Navigation zur details-Route von der Seite für die monkeys-Route die MonkeyDetailPage anzeigt. Entsprechend zeigt die Navigation zur details-Route von der Seite für die elephants-Route die ElephantDetailPage an. Weitere Informationen finden Sie unter Kontextbezogene Navigation.

Hinweis

Die Registrierung von Seiten, deren Routen mit der Routing.RegisterRoute-Methode registriert wurden, kann bei Bedarf mit der Routing.UnRegisterRoute-Methode aufgehoben werden.

Durchführen der Navigation

Zuerst muss ein Verweis auf die Unterklasse Shell abgerufen werden, um die Navigation durchzuführen. Dieser Verweis kann über die Shell.Current Eigenschaft abgerufen werden. Die Navigation kann dann durch Aufrufen der GoToAsync-Methode für das Shell-Objekt durchgeführt werden. Diese Methode navigiert zu einem ShellNavigationState und gibt einen Task zurück, der nach Ende der Navigationsanimation abgeschlossen wird. Das ShellNavigationState-Objekt wird durch die GoToAsync-Methode aus einer string oder einem Uri gebildet, und verfügt über eine Location-Eigenschaft, die auf das Argument string oder Uri festgelegt ist.

Wichtig

Erfolgt die Navigation zu einer Route aus der visuellen Shell-Hierarchie, wird kein Navigationsstapel erstellt. Erfolgt die Navigation jedoch zu einer Seite, die sich nicht in der visuellen Shell-Hierarchie befindet, wird kein Navigationsstapel erstellt.

Der aktuelle Navigationsstatus des Shell-Objekts kann über die Shell.Current.CurrentState-Eigenschaft abgerufen werden, die den URI der angezeigten Route in der Location-Eigenschaft enthält.

Absolute Routen

Die Navigation kann durch Angeben eines gültigen absoluten URIs als Argument für die GoToAsync-Methode durchgeführt werden:

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

In diesem Beispiel erfolgt die Navigation zur Seite für die monkeys-Route, wobei die Route im ShellContent-Objekt definiert wird. Das ShellContent-Objekt, das die monkeys-Route darstellt, ist ein untergeordnetes Element eines FlyoutItem-Objekts mit der Route animals.

Relative Routen

Die Navigation kann auch durch Angeben eines gültigen relativen URIs als Argument für die GoToAsync-Methode durchgeführt werden. Das Routingsystem versucht daher, den URI mit einem ShellContent-Objekt abzugleichen. Wenn also alle Routen in einer App eindeutig sind, kann die Navigation nur durch die Angabe des eindeutigen Routennamens als relativer URI erfolgen.

Die folgenden relativen Routenformate werden unterstützt:

Format Beschreibung
route In der Routenhierarchie wird von der aktuellen Position aus nach oben nach der angegebenen Route gesucht. Die übereinstimmende Seite wird per Push an den Navigationsstapel übertragen.
/route In der Routenhierarchie wird von der aktuellen Position aus nach unten nach der angegebenen Route gesucht. Die übereinstimmende Seite wird per Push an den Navigationsstapel übertragen.
//route In der Routenhierarchie wird von der aktuellen Position aus nach oben nach der angegebenen Route gesucht. Die übereinstimmende Seite ersetzt den Navigationsstapel.
///route In der Routenhierarchie wird von der aktuellen Position aus nach unten nach der angegebenen Route gesucht. Die übereinstimmende Seite ersetzt den Navigationsstapel.

Im folgenden Beispiel wird zur Seite für die monkeydetails-Route navigiert:

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

In diesem Beispiel wird die Hierarchie aufwärts nach der monkeyDetails-Route durchsucht, bis die übereinstimmende Seite gefunden wird. Wenn die Seite gefunden wird, wird sie per Push an den Navigationsstapel übertragen.

Kontextbezogene Navigation

Relative Routen ermöglichen kontextbezogene Navigation. Nehmen wir beispielsweise die folgende Routenhierarchie:

monkeys
  details
bears
  details

Wenn die registrierte Seite für die monkeys-Route angezeigt wird, wird durch die Navigation zur details-Route die registrierte Seite für die monkeys/details-Route angezeigt. Wenn die registrierte Seite für die bears-Route angezeigt wird, wird durch die Navigation zur details-Route entsprechend die registrierte Seite für die bears/details-Route angezeigt. Informationen zum Registrieren der Routen in diesem Beispiel finden Sie unter Registrieren von Seitenrouten.

Rückwärtsnavigation

Die Rückwärtsnavigation kann erfolgen, indem Sie ".." als Argument zur GoToAsync-Methode hinzufügen.

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

Die Rückwärtsnavigation mit ".." kann auch mit einer Route kombiniert werden:

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

In diesem Beispiel wird die Rückwärtsnavigation und dann die Navigation zur angegebenen Route durchgeführt.

Wichtig

Die Rückwärtsnavigation und die Navigation zu einer angegebenen Route sind nur möglich, wenn die Rückwärtsnavigation Sie zur aktuellen Position in der Routenhierarchie bringt, damit Sie zur angegebenen Route navigieren können.

Ebenso ist es möglich, mehrmals rückwärts und dann zu einer bestimmten Route zu navigieren:

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

In diesem Beispiel wird zweimal die Rückwärtsnavigation und dann die Navigation zur angegebenen Route durchgeführt.

Darüber hinaus können Daten bei der Rückwärtsnavigation durch Abfrageeigenschaften übergeben werden:

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

In diesem Beispiel wird die Rückwärtsnavigation durchgeführt, und der Abfrageparameterwert wird an den Abfrageparameter auf der vorherigen Seite übergeben.

Hinweis

Abfrageparameter können an jede Rückwärtsnavigationsanforderung angehängt werden.

Weitere Informationen zum Übergeben von Daten bei der Navigation finden Sie unter Übergeben von Daten.

Ungültige Routen

Die folgenden Routenformate sind ungültig:

Format Erklärung
//page oder ///page Globale Routen dürfen derzeit nicht die einzige Seite im Navigationsstapel sein. Aus diesem Grund wird das absolute Routing zu globalen Routen nicht unterstützt.

Die Verwendung dieser Routenformate führt dazu, dass eine Exception ausgelöst wird.

Warnung

Der Versuch, zu einer nicht vorhandenen Route zu navigieren führt dazu, dass eine ArgumentException ausgelöst wird.

Debuggen der Navigation

Einige der Shell-Klassen werden mit dem DebuggerDisplayAttribute ergänzt, das festlegt, wie eine Klasse oder das Feld vom Debugger angezeigt wird. Dies kann helfen, Navigationsanforderungen zu debuggen, indem Daten angezeigt werden, die sich auf die Navigationsanforderung beziehen. Der folgende Screenshot zeigt beispielsweise die Eigenschaften CurrentItem und CurrentState des Shell.Current-Objekts an:

Screenshot des Debuggers.

In diesem Beispiel zeigt die CurrentItem-Eigenschaft vom Typ FlyoutItem den Titel und die Route des FlyoutItem-Objekts an. In ähnlicher Weise zeigt die Eigenschaft CurrentState vom Typ ShellNavigationState den URI der angezeigten Route innerhalb der Shell-App an.

Die Klasse Tab definiert eine Stack-Eigenschaft vom Typ IReadOnlyList<Page>, die den aktuellen Navigationsstapel innerhalb der Tab darstellt. Die Klasse bietet auch die folgenden überschreibbaren Navigationsmethoden:

  • GetNavigationStack, liefert IReadOnlyList<Page>, den aktuellen Navigationsstapel.
  • OnInsertPageBefore: Wird aufgerufen, wenn INavigation.InsertPageBefore aufgerufen wird.
  • OnPopAsync: Gibt Task<Page> zurück, und wird aufgerufen, wenn INavigation.PopAsync aufgerufen wird.
  • OnPopToRootAsync: Gibt Task zurück, und wird aufgerufen, wenn INavigation.OnPopToRootAsync aufgerufen wird.
  • OnPushAsync: Gibt Task zurück, und wird aufgerufen, wenn INavigation.PushAsync aufgerufen wird.
  • OnRemovePage: Wird aufgerufen, wenn INavigation.RemovePage aufgerufen wird.

Im folgenden Beispiel sehen Sie, wie die OnRemovePage-Methode überschrieben wird:

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

        // Custom logic
    }
}

In diesem Beispiel sollten in Ihrer visuellen Shellhierarchie MyTab-Objekte anstelle von Tab-Objekten verwendet werden.

Die Shell-Klasse definiert das Navigating-Ereignis, das ausgelöst wird, kurz bevor die Navigation entweder aufgrund von programmgesteuerter Navigation oder Benutzerinteraktion erfolgt. Das ShellNavigatingEventArgs-Objekt, das das Navigating-Ereignis begleitet, stellt die folgenden Eigenschaften bereit:

Eigenschaft Typ Beschreibung
Current ShellNavigationState Der URI der aktuellen Seite.
Source ShellNavigationSource Der Typ der erfolgten Navigation.
Target ShellNavigationState Der URI, der darstellt, wohin die Navigation führt.
CanCancel bool Ein Wert, der angibt, ob ein Abbruch der Navigation möglich ist.
Cancelled bool Ein Wert, der angibt, ob die Navigation abgebrochen wurde.

Außerdem stellt die ShellNavigatingEventArgs-Klasse eine Cancel-Methode bereit, die verwendet werden kann, um die Navigation abzubrechen. Zusätzlich stellt sie eine GetDeferral-Methode bereit, die ein ShellNavigatingDeferral-Token zurückgibt, das verwendet werden kann, um die Navigation abzuschließen. Weitere Informationen zur Navigationsverzögerung finden Sie unter Navigationsverzögerung.

Die Shell-Klasse definiert außerdem ein Navigated-Ereignis, das ausgelöst wird, wenn die Navigation abgeschlossen ist. Das ShellNavigatedEventArgs-Objekt, das das Navigated-Ereignis begleitet, stellt die folgenden Eigenschaften bereit:

Eigenschaft Typ Beschreibung
Current ShellNavigationState Der URI der aktuellen Seite.
Previous ShellNavigationState Der URI der vorherigen Seite.
Source ShellNavigationSource Der Typ der erfolgten Navigation.

Wichtig

Die OnNavigating-Methode wird aufgerufen, wenn das Navigating-Ereignis ausgelöst wird. Ebenso wird die OnNavigated-Methode aufgerufen, wenn das Navigated-Ereignis ausgelöst wird. Beide Methoden können in der Shell-Unterklasse überschrieben werden, um Navigationsanforderungen abzufangen.

Die Klassen ShellNavigatedEventArgs und ShellNavigatingEventArgs verfügen beide über Source-Eigenschaften vom Typ ShellNavigationSource. Diese Enumeration stellt die folgenden Werte bereit:

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

Aus diesem Grund kann die Navigation in einer OnNavigating-Überschreibung abgefangen werden, und Aktionen können basierend auf der Navigationsressource ausgeführt werden. Der folgende Code zeigt beispielsweise, wie die Rückwärtsnavigation abgebrochen wird, wenn die Daten auf der Seite nicht gespeichert wurden:

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

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

Die Shellnavigation kann basierend auf der Benutzerauswahl abgefangen und abgeschlossen oder abgebrochen werden. Dies kann erreicht werden, indem Sie die OnNavigating-Methode in Ihrer Shell-Unterklasse überschreiben und die GetDeferral-Methode für das ShellNavigatingEventArgs-Objekt aufrufen. Diese Methode gibt ein ShellNavigatingDeferral-Token zurück, das über eine Complete-Methode verfügt, die zum Vervollständigen der Navigationsanforderung verwendet werden kann:

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 diesem Beispiel wird ein Aktionsblatt angezeigt, in dem der Benutzer aufgefordert wird, die Navigationsanforderung abzuschließen oder abzubrechen. Die Navigation wird abgebrochen, indem die Cancel-Methode für das ShellNavigatingEventArgs-Objekt aufgerufen wird. Die Navigation wird durch Aufrufen der Complete-Methode für das ShellNavigatingDeferral-Token abgeschlossen, das von der GetDeferral-Methode für das ShellNavigatingEventArgs-Objekt abgerufen wurde.

Warnung

Durch die GoToAsync-Methode wird eine InvalidOperationException ausgelöst, wenn ein Benutzer versucht, zu navigieren, während eine ausstehende Navigationsverzögerung vorliegt.

Übergeben von Daten

Primitive Daten können als zeichenfolgenbasierte Abfrageparameter übergeben werden, wenn eine URI-basierte programmgesteuerte Navigation ausgeführt wird. Dies wird durch Anhängen von ? nach einer Route, gefolgt von einer Abfrageparameter-ID (=) und einem Wert erreicht:

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

Dieses Beispiel ruft den aktuell ausgewählten Elefanten in CollectionView ab und navigiert zur Route elephantdetails, wobei elephantName als Abfrageparameter übergeben wird.

Weitergabe von objektbasierten Navigationsdaten zur Mehrfachnutzung

Mehrfach verwendbare objektbasierte Navigationsdaten können mit einer GoToAsync-Überladung übergeben werden, die ein IDictionary<string, object>-Argument angibt:

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 diesem Beispiel wird der aktuell ausgewählte Bär im CollectionView als Animal abgerufen. Das Animal-Objekt wird zu Dictionary mit dem Schlüssel Bear hinzugefügt. Dann wird die Navigation zur Route beardetails durchgeführt, wobei Dictionary als Navigationsparameter übergeben wird.

Alle Daten, die als IDictionary<string, object>-Argument übergeben werden, bleiben während der gesamten Lebensdauer der Seite im Speicher und werden erst freigegeben, wenn die Seite aus dem Navigationsstapel entfernt wird. Dies kann problematisch sein, wie das folgende Szenario zeigt:

  1. Page1 navigiert mit der Methode GoToAsync zu Page2 und übergibt ein Objekt namens MyData. Page2 erhält dann MyData als Abfrageparameter.
  2. Page2 navigiert zu Page3 unter Verwendung der Methode GoToAsync, ohne Daten zu übergeben.
  3. Page3 navigiert rückwärts mit der Methode GoToAsync. Page2 erhält dann wieder MyData als Abfrageparameter.

Dies ist zwar in vielen Fällen wünschenswert, aber wenn es nicht erwünscht ist, sollten Sie das IDictionary<string, object>-Argument mit der Methode Clear löschen, nachdem es zum ersten Mal von einer Seite empfangen wurde.

Übergabe von objektbasierten Navigationsdaten zur einmaligen Verwendung

Einmalige objektbasierte Navigationsdaten können mit einer GoToAsync-Überladung übergeben werden, die ein ShellNavigationQueryParameters-Argument angibt. Ein ShellNavigationQueryParameters-Objekt ist für Navigationsdaten zur einmaligen Verwendung gedacht, die nach der Navigation gelöscht werden. Das folgende Beispiel zeigt die Navigation bei der Übergabe von Einwegdaten:

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

Dieses Beispiel ruft den aktuell ausgewählten Bären im CollectionView als Animal ab, der dem ShellNavigationQueryParameters-Objekt hinzugefügt wird. Dann wird die Navigation zur beardetails-Route durchgeführt, wobei das ShellNavigationQueryParameters-Objekt als Navigationsparameter übergeben wird. Nach erfolgter Navigation werden die Daten im Objekt ShellNavigationQueryParameters gelöscht.

Empfangen von Navigationsdaten

Es gibt zwei Ansätze zum Empfangen von Navigationsdaten:

  1. Die Klasse, die die Seite darstellt, zu der navigiert wird, oder die Klasse für den BindingContext der Seite kann um ein QueryPropertyAttribute für jeden Abfrageparameter ergänzt werden. Weitere Informationen finden Sie unter Verarbeiten von Navigationsdaten mithilfe von Abfrageeigenschaftsattributen.
  2. Die Klasse, die die Seite darstellt, zu der navigiert wird, oder die Klasse für den BindingContext der Seite kann die IQueryAttributable-Schnittstelle implementieren. Weitere Informationen finden Sie unter Verarbeiten von Navigationsdaten mit einer einzelnen Methode.

Verarbeiten von Navigationsdaten mithilfe von Abfrageeigenschaftsattributen

Navigationsdaten können empfangen werden, indem die empfangende Klasse mit einem QueryPropertyAttribute für jeden stringbasierten Abfrageparameter, objektbasierten Navigationsparameter oder ShellNavigationQueryParameters-Objekt dekoriert wird:

[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 diesem Beispiel gibt das erste Argument für QueryPropertyAttribute den Namen der Eigenschaft an, die die Daten erhalten soll, während das zweite Argument die Parameter-ID angibt. Daher gibt QueryPropertyAttribute im obigen Beispiel an, dass die Eigenschaft Bear die im Navigationsparameter Bear im Methodenaufruf GoToAsync übergebenen Daten erhält.

Wichtig

Zeichenfolgenbasierte Abfrageparameterwerte, die über QueryPropertyAttribute empfangen werden, werden automatisch URL-decodiert.

Warnung

Das Empfangen von Navigationsdaten mithilfe der QueryPropertyAttribute Funktion ist nicht sicher und sollte nicht mit vollständiger Kürzung oder NativeAOT verwendet werden. Stattdessen sollten Sie die IQueryAttributable Schnittstelle für Typen implementieren, die Abfrageparameter akzeptieren müssen. Weitere Informationen finden Sie unter Verarbeiten von Navigationsdaten mithilfe einer einzelnen Methode, Kürzen einer .NET MAUI-App und nativer AOT-Bereitstellung.

Verarbeiten von Navigationsdaten mit einer einzelnen Methode

Navigationsdaten können empfangen werden, indem die IQueryAttributable-Schnittstelle für die empfangende Klasse implementiert wird. Die IQueryAttributable-Schnittstelle gibt an, dass die implementierende Klasse die ApplyQueryAttributes-Methode implementieren muss. Diese Methode verfügt über ein query-Argument vom Typ IDictionary<string, object>, das alle während der Navigation übergebenen Daten enthält. Jeder Schlüssel im Wörterbuch ist eine Abfrageparameter-ID, deren Wert dem Objekt entspricht, das die Daten darstellt. Der Vorteil dieser Vorgehensweise besteht darin, dass Navigationsdaten mit einer einzigen Methode verarbeitet werden können. Dies kann hilfreich sein, wenn Sie über mehrere Navigationsdatenelemente verfügen, die als Ganzes verarbeitet werden müssen.

Das folgende Beispiel veranschaulicht eine Ansichtsmodellklasse, die die IQueryAttributable-Schnittstelle implementiert:

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 diesem Beispiel ruft die ApplyQueryAttributes-Methode das Objekt ab, das dem Monkey-Schlüssel im query-Wörterbuch entspricht, der als Argument an den GoToAsync-Methodenaufruf übergeben wurde.

Wichtig

Stringbasierte Abfrageparameterwerte, die über die IQueryAttributable-Schnittstelle empfangen werden, werden nicht automatisch URL-dekodiert.

Übergeben und Verarbeiten mehrerer Datenelemente

Es können mehrere stringbasierte Abfrageparameter übergeben werden, indem sie mit & verbunden werden. Der folgende Code übergibt beispielsweise zwei Datenelemente:

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

Dieses Codebeispiel ruft den aktuell ausgewählten Elefanten in der CollectionView ab und navigiert zur elephantdetails-Route, wobei elephantName und elephantLocation als Abfrageparameter übergeben werden.

Damit Sie mehrere Datenelemente empfangen können, kann die Klasse, die die Seite darstellt, zu der navigiert wird, oder die Klasse für den BindingContext der Seite um ein QueryPropertyAttribute für jeden Abfrageparameter ergänzt werden:

[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 diesem Beispiel wird die Klasse mit einem QueryPropertyAttribute für jeden Abfrageparameter ergänzt. Das erste QueryPropertyAttribute gibt an, dass die Name-Eigenschaft die Daten empfängt, die im name-Abfrageparameter übergeben werden. Das zweite QueryPropertyAttribute gibt an, dass die Location-Eigenschaft die Daten empfängt, die im location-Abfrageparameter übergeben werden. In beiden Fällen werden die Abfrageparameterwerte im URI im GoToAsync-Methodenaufruf angegeben.

Warnung

Das Empfangen von Navigationsdaten mithilfe der QueryPropertyAttribute Funktion ist nicht sicher und sollte nicht mit vollständiger Kürzung oder NativeAOT verwendet werden. Stattdessen sollten Sie die IQueryAttributable Schnittstelle für Typen implementieren, die Abfrageparameter akzeptieren müssen. Weitere Informationen finden Sie unter Trim a .NET MAUI app and Native AOT deployment.

Alternativ können Navigationsdaten von einer einzelnen Methode verarbeitet werden, indem die IQueryAttributable-Schnittstelle für die Klasse implementiert wird, die die Seite darstellt, zu der navigiert wird, oder für die Klasse für den BindingContext der Seite:

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 diesem Beispiel ruft die ApplyQueryAttributes-Methode den Wert der Abfrageparameter name und location aus dem URI im GoToAsync-Methodenaufruf ab.

Hinweis

Stringbasierte Abfrageparameter und objektbasierte Navigationsparameter können gleichzeitig übergeben werden, wenn eine routenbasierte Navigation durchgeführt wird.

Verhalten der Zurück-Schaltfläche

Die Darstellung und das Verhalten der ZURÜCK-TASTE kann neu definiert werden, indem die angefügte Eigenschaft BackButtonBehavior auf ein BackButtonBehavior-Objekt festgelegt wird. Die BackButtonBehavior-Klasse definiert die folgenden Eigenschaften:

  • Command, vom Typ ICommand: wird ausgeführt, wenn die ZURÜCK-TASTE gedrückt wird.
  • CommandParameter, vom Typ object: Parameter, der an den Command übergeben wird.
  • IconOverride, vom Typ ImageSource: Symbol für die ZURÜCK-TASTE.
  • IsEnabled, vom Typ boolean: gibt an, ob die ZURÜCK-TASTE aktiviert ist. Der Standardwert ist true.
  • IsVisible, vom Typ boolean, zeigt an, ob die Zurück-Taste sichtbar ist. Der Standardwert ist true.
  • TextOverride, vom Typ string: Text, der für die ZURÜCK-TASTE verwendet wird.

Alle diese Eigenschaften werden durch BindableProperty-Objekte gestützt, was bedeutet, dass die Eigenschaften Ziele von Datenverbindungen sein können. Jede BindableProperty hat einen OneTime-Bindungsmodus, was bedeutet, dass Daten von der Quelle zum Ziel gehen, aber nur, wenn sich der BindingContext ändert.

Alle diese Eigenschaften werden durch BindableProperty-Objekte gestützt, was bedeutet, dass die Eigenschaften Ziele von Datenverbindungen sein können. Die Objekte Command, CommandParameter, IconOveride und TextOverideBindableProperty verfügen über OneTime-Bindungsmodi, was bedeutet, dass Daten von der Quelle zum Ziel übertragen werden, aber nur, wenn sich BindingContext ändert. Die Objekte IsEnabled und IsVisibleBindableProperty haben die OneWay-Bindungsmodi, was bedeutet, dass Daten von der Quelle zum Ziel gelangen.

Der folgende Code zeigt ein Beispiel für das erneute Definieren der Darstellung und des Verhaltens der ZURÜCK-TASTE.

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

Die Command-Eigenschaft wird auf einen ICommand festgelegt, der ausgeführt wird, wenn die ZURÜCK-TASTE gedrückt wird, und die IconOverride-Eigenschaft wird auf das Symbol festgelegt, das für die ZURÜCK-TASTE verwendet wird:

Screenshot: Außerkraftsetzung des Schaltflächensymbols „Zurück“ in der Shell