Sdílet prostřednictvím


Navigace

Tip

Tento obsah je výňatek z elektronické knihy, vzory podnikových aplikací pomocí .NET MAUI, dostupné na .NET Docs nebo jako zdarma ke stažení PDF, které lze číst offline.

Vzory podnikových aplikací pomocí úvodní miniatury eBooku .NET MAUI

.NET MAUI zahrnuje podporu navigace na stránce, což obvykle vede k interakci uživatele s uživatelským rozhraním nebo ze samotné aplikace v důsledku interních změn stavu řízeného logikou. Navigace ale může být složitá pro implementaci v aplikacích, které používají model model-View-ViewModel (MVVM), protože musí být splněny následující výzvy:

  • Identifikace zobrazení, ke kterému se má přejít, pomocí přístupu, který nezavádí úzkou vazbu a závislosti mezi zobrazeními.
  • Koordinuje proces, podle kterého se má zobrazení přejít, vytvoří instanci a inicializuje. Při použití MVVM je potřeba vytvořit instanci zobrazení a model zobrazení a přidružit k sobě prostřednictvím kontextu vazby zobrazení. Když aplikace používá kontejner injektáž závislostí, může vytvoření instance zobrazení a modelů zobrazení vyžadovat konkrétní stavební mechanismus.
  • Bez ohledu na to, jestli se má provést navigace podle prvního zobrazení, nebo navigace podle modelu. Při první navigaci zobrazení se stránka, na které chcete přejít, odkazuje na název typu zobrazení. Během navigace se vytvoří instance zadaného zobrazení spolu s odpovídajícím modelem zobrazení a dalšími závislými službami. Alternativním přístupem je použít navigaci typu view-model-first, kde stránka, na které chcete přejít, odkazuje na název typu modelu zobrazení.
  • Určení toho, jak čistě oddělit navigační chování aplikace napříč zobrazeními a modely zobrazení. Model MVVM odděluje uživatelské rozhraní aplikace a jeho prezentaci a obchodní logiku, ale neposkytuje přímý mechanismus pro jejich propojení. Chování navigace v aplikaci ale často pokrývá části uživatelského rozhraní a prezentace aplikace. Uživatel bude často inicializovat navigaci ze zobrazení a zobrazení bude nahrazeno v důsledku navigace. Navigace však může být často potřeba iniciovat nebo koordinovat z modelu zobrazení.
  • Určení způsobu předávání parametrů během navigace pro inicializační účely Pokud například uživatel přejde do zobrazení pro aktualizaci podrobností objednávky, budou se data objednávky muset předat do zobrazení, aby mohla zobrazit správná data.
  • Koordinace navigace s cílem zajistit, aby byla dodržena konkrétní obchodní pravidla. Uživatelům se například může zobrazit výzva před přechodem z zobrazení, aby mohli opravit všechna neplatná data nebo být vyzváni k odeslání nebo zahození jakýchkoli změn dat provedených v zobrazení.

Tato kapitola řeší tyto problémy tím, že prezentuje třídu navigační služby s názvem MauiNavigationService , která se používá k provádění navigace na první stránce modelu zobrazení.

Poznámka:

Aplikace MauiNavigationService je zjednodušená a nepokrývá všechny možné typy navigace. Typy navigace, které vaše aplikace potřebuje, můžou vyžadovat další funkce.

Navigační logika se může nacházet v kódu zobrazení nebo v modelu zobrazení vázaném na data. I když umístění navigační logiky do zobrazení může být nejjednodušším přístupem, není snadné ji testovat prostřednictvím testů jednotek. Vložení navigační logiky do tříd modelu zobrazení znamená, že logiku je možné ověřit pomocí testů jednotek. Kromě toho model zobrazení může implementovat logiku pro řízení navigace, aby se zajistilo vynucení určitých obchodních pravidel. Aplikace například nemusí uživateli povolit navigaci mimo stránku, aniž by nejprve zajistila platnost zadaných dat.

Navigační služba se obvykle vyvolává z modelů zobrazení, aby se podpořila testovatelnost. Přechod na zobrazení z modelů zobrazení však vyžaduje, aby modely zobrazení odkazovaly na zobrazení, a zejména zobrazení, ke kterým není aktivní model zobrazení přidružený, což se nedoporučuje. Proto uvedený typ MauiNavigationService modelu zobrazení určuje jako cíl, na který se má přejít.

Multiformní aplikace eShop používá MauiNavigationService třídu k zajištění první navigace v modelu zobrazení. Tato třída implementuje INavigationService rozhraní, které je znázorněno v následujícím příkladu kódu:

public interface INavigationService
{
    Task InitializeAsync();

    Task NavigateToAsync(string route, IDictionary<string, object> routeParameters = null);

    Task PopAsync();
}

Toto rozhraní určuje, že implementovat třídu musí poskytovat následující metody:

Způsob Účel
InitializeAsync Při spuštění aplikace provede navigaci na jednu ze dvou stránek.
NavigateToAsync(string route, IDictionary<string, object> routeParameters = null) Provede hierarchickou navigaci na zadanou stránku pomocí registrované navigační trasy. Volitelně můžete předat parametry pojmenované trasy, které se mají použít ke zpracování na cílové stránce.
PopAsync Odebere aktuální stránku z navigačního zásobníku.

Poznámka:

Rozhraní INavigationService obvykle také určuje metodu GoBackAsync , která se používá k programovému návratu na předchozí stránku v navigačním zásobníku. Tato metoda však v aplikaci eShop pro více platforem chybí, protože není nutná.

Vytvoření instance MauiNavigationService

Třída MauiNavigationService , která implementuje INavigationService rozhraní, je registrována jako singleton s kontejnerem injektáž závislostí v MauiProgram.CreateMauiApp() metodě, jak je znázorněno v následujícím příkladu kódu:

mauiAppBuilder.Services.AddSingleton<INavigationService, MauiNavigationService>();

Rozhraní INavigationService pak lze vyřešit jeho přidáním do konstruktoru našich zobrazení a modelů zobrazení, jak je znázorněno v následujícím příkladu kódu:

public AppShell(INavigationService navigationService)

Tím se vrátí odkaz na MauiNavigationService objekt uložený v kontejneru injektáže závislostí.

Třída ViewModelBase ukládá MauiNavigationService instanci do NavigationService vlastnosti typu INavigationService. Proto všechny třídy modelu zobrazení, které jsou odvozeny z ViewModelBase třídy, mohou použít NavigationService vlastnost pro přístup k metodám určeným rozhraním INavigationService .

Zpracování navigačních požadavků

.NET MAUI nabízí několik způsobů navigace v rámci aplikace. Tradiční způsob navigace je s NavigationPage třídou, která implementuje hierarchické navigační prostředí, ve kterém může uživatel podle potřeby procházet stránky, dopředu a dozadu. Aplikace eShop používá komponentu Shell jako kořenový kontejner aplikace a jako navigačního hostitele. Další informace o navigaci prostředí naleznete v tématu Navigace prostředí na webu Microsoft Developer Center.

Navigace se provádí uvnitř tříd modelu zobrazení vyvoláním jedné z NavigateToAsync metod, zadáním cesty trasy pro stránku, na kterou se prochází, jak je znázorněno v následujícím příkladu kódu:

await NavigationService.NavigateToAsync("//Main");

Následující příklad kódu ukazuje metodu NavigateToAsync poskytovanou MauiNavigationService třídou:

public Task NavigateToAsync(string route, IDictionary<string, object> routeParameters = null)
{
    return
        routeParameters != null
            ? Shell.Current.GoToAsync(route, routeParameters)
            : Shell.Current.GoToAsync(route);
}

Ovládací prvek .NET MAUIShell už znáte navigaci založenou NavigateToAsync na trasách, takže metoda funguje na maskování této funkce. Metoda NavigateToAsync umožňuje zadat navigační data jako argument, který se předává do modelu zobrazení, do kterého se přechází, kde se obvykle používá k provedení inicializace. Další informace naleznete v tématu Předávání parametrů během navigace.

Důležité

Navigace v .NET MAUIexistuje několik způsobů. Jedná se MauiNavigationService konkrétně o sestavení pro práci s Shell. Pokud používáte NavigationPage nebo TabbedPage používáte jiný navigační mechanismus, musí být tato směrovací služba aktualizována, aby fungovala pomocí těchto součástí.

Abychom mohli registrovat trasy, MauiNavigationService potřebujeme zadat informace o směrování z XAML nebo do kódu. Následující příklad ukazuje registraci tras prostřednictvím XAML.

<?xml version="1.0" encoding="UTF-8" ?>
<Shell
    xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:views="clr-namespace:eShop.Views"
    x:Class="eShop.AppShell">

    <!-- Omitted for brevity -->

    <FlyoutItem >
        <ShellContent x:Name="login" ContentTemplate="{DataTemplate views:LoginView}" Route="Login" />
    </FlyoutItem>

    <TabBar x:Name="main" Route="Main">
        <ShellContent Title="CATALOG" Route="Catalog" Icon="{StaticResource CatalogIconImageSource}" ContentTemplate="{DataTemplate views:CatalogView}" />
        <ShellContent Title="PROFILE" Route="Profile" Icon="{StaticResource ProfileIconImageSource}" ContentTemplate="{DataTemplate views:ProfileView}" />
    </TabBar>
</Shell>

V tomto příkladu ShellContent objekty uživatelského TabBar rozhraní nastavuje jejich Route vlastnost. Toto je upřednostňovaná metoda registrace tras pro objekty uživatelského rozhraní, které jsou řízeny objekty Shell.

Pokud máme objekty, které se později přidají do navigačního zásobníku, budeme je muset přidat prostřednictvím kódu. Následující příklad ukazuje registraci tras v kódu za sebou.

Routing.RegisterRoute("Filter", typeof(FiltersView));
Routing.RegisterRoute("Basket", typeof(BasketView));

V kódu za sebou zavoláme metodu Routing.RegisterRoute , která jako první parametr přebírá název trasy a typ zobrazení jako druhý parametr. Když model zobrazení používá NavigationService vlastnost k navigaci, objekt aplikace Shell vyhledá registrované trasy a nasdílí je do navigačního zásobníku.

Po vytvoření a přechodu na ApplyQueryAttributes zobrazení se spustí a InitializeAsync metody přidruženého modelu zobrazení. Další informace naleznete v tématu Předávání parametrů během navigace.

Při spuštění Shell aplikace se objekt nastaví jako kořenové zobrazení aplikace. Po nastavení Shell se použije k řízení registrace tras a bude k dispozici v kořenovém adresáři naší aplikace. Shell Po vytvoření můžeme počkat na jeho připojení k aplikaci pomocí OnParentSet metody inicializace navigační trasy. Následující příklad kódu ukazuje tuto metodu:

protected override async void OnParentSet()
{
    base.OnParentSet();

    if (Parent is not null)
    {
        await _navigationService.InitializeAsync();
    }
}

Metoda používá instanci, z INavigationService níž je poskytován konstruktor z injektáže závislostí a vyvolá jeho InitializeAsync metodu.

Následující příklad kódu ukazuje implementaci MauiNavigationService.InitializeAsync metody:

public Task InitializeAsync()
{
    return NavigateToAsync(string.IsNullOrEmpty(_settingsService.AuthAccessToken)
        ? "//Login"
        : "//Main/Catalog");
}

Trasa //Main/Catalog se přejde, pokud má aplikace přístupový token uložený v mezipaměti, který se používá k ověřování. //Login V opačném případě se trasa přejde na.

Předávání parametrů během navigace

Metoda NavigateToAsync určená INavigationService rozhraním umožňuje zadat navigační data jako IDictionary<string, object> data, která se předávají do modelu zobrazení, do kterého se obvykle používá k inicializaci.

Třída například ProfileViewModel obsahuje spuštěnou OrderDetailCommand třídu, když uživatel vybere objednávku na ProfileView stránce. Následně se spustí OrderDetailAsync metoda, která je zobrazena v následujícím příkladu kódu:

private async Task OrderDetailAsync(Order order)
{
    if (order is null)
    {
        return;
    }

    await NavigationService.NavigateToAsync(
        "OrderDetail",
        new Dictionary<string, object>{ { "OrderNumber", order.OrderNumber } });
}

Tato metoda vyvolá navigaci na trasu OrderDetail a předá informace o čísle objednávky pořadí, které uživatel vybral. Když architektura injektáže závislostí vytvoří pro trasu OrderDetail spolu s OrderDetailViewModel třídou, která je přiřazena k zobrazení BindingContext.OrderDetailView Do OrderDetailViewModel něj je přidaný atribut, který umožňuje přijímat data z navigační služby, jak je znázorněno v příkladu kódu níže.

[QueryProperty(nameof(OrderNumber), "OrderNumber")]
public class OrderDetailViewModel : ViewModelBase
{
    public int OrderNumber { get; set; }
}

Tento QueryProperty atribut nám umožňuje poskytnout parametr pro vlastnost, která mapuje hodnoty na a klíč k vyhledání hodnot ze slovníku parametrů dotazu. V tomto příkladu se během NavigateToAsync volání zadal klíč OrderNumber a hodnota čísla objednávky. Model zobrazení našel klíč OrderNumber a namapoval hodnotu na OrderNumber vlastnost. Vlastnost OrderNumber lze použít později k načtení úplných podrobností objednávky z OrderService instance.

Vyvolání navigace pomocí chování

Navigace se obvykle aktivuje ze zobrazení interakcí uživatele. Například provede LoginView navigaci po úspěšném ověření. Následující příklad kódu ukazuje, jak je navigace vyvolána chováním:

<WebView>
    <WebView.Behaviors>
        <behaviors:EventToCommandBehavior
            EventName="Navigating"
            EventArgsConverter="{StaticResource WebNavigatingEventArgsConverter}"
            Command="{Binding NavigateCommand}" />
    </WebView.Behaviors>
</WebView>

Za běhu EventToCommandBehavior bude reagovat na interakci s .WebView WebView Když přejdete na webovou stránku, Navigating událost se aktivuje, která spustí NavigateCommand v LoginViewModel. Ve výchozím nastavení se argumenty události události předávají příkazu. Tato data se převedou tak, jak se předávají mezi zdrojem a cílem převaděčem zadaným ve EventArgsConverter vlastnosti, která vrací Url z WebNavigatingEventArgs. Proto se při NavigationCommand spuštění Url webové stránky předá jako parametr registrované akci.

Následně provede NavigationCommand metodu NavigateAsync , která je zobrazena v následujícím příkladu kódu:

private async Task NavigateAsync(string url)
{
    // Omitted for brevity.
    if (!string.IsNullOrWhiteSpace(accessToken))
    {
        _settingsService.AuthAccessToken = accessToken;
        _settingsService.AuthIdToken = authResponse.IdentityToken;
        await NavigationService.NavigateToAsync("//Main/Catalog");
    }
}

Tato metoda vyvolá NavigationService směrování aplikace na trasu //Main/Catalog .

Potvrzení nebo zrušení navigace

Aplikace může během operace navigace potřebovat interakci s uživatelem, aby uživatel mohl potvrdit nebo zrušit navigaci. To může být nutné například v případě, že se uživatel pokusí přejít před úplným dokončením stránky pro zadávání dat. V takovém případě by aplikace měla poskytnout oznámení, které uživateli umožní přejít mimo stránku nebo zrušit navigační operaci předtím, než k ní dojde. Toho lze dosáhnout ve třídě modelu zobrazení pomocí odpovědi z oznámení, která určuje, zda je vyvolána nebo není vyvolána navigace.

Shrnutí

.NET MAUI zahrnuje podporu navigace na stránce, která obvykle vede k interakci uživatele s uživatelským rozhraním nebo ze samotné aplikace v důsledku interních změn stavu řízeného logikou. Navigace ale může být složitá pro implementaci v aplikacích, které používají model MVVM.

Tato kapitola představila třídu NavigationService, která se používá k provádění první navigace modelu zobrazení z modelů zobrazení. Umístění navigační logiky do tříd modelu zobrazení znamená, že logiku je možné provádět prostřednictvím automatizovaných testů. Kromě toho model zobrazení může implementovat logiku pro řízení navigace, aby se zajistilo vynucení určitých obchodních pravidel.