Bagikan melalui


Navigasi

Tip

Konten ini adalah kutipan dari eBook, Pola Aplikasi Perusahaan Menggunakan .NET MAUI, tersedia di .NET Docs atau sebagai PDF gratis yang dapat diunduh yang dapat dibaca secara offline.

Pola Aplikasi Perusahaan Menggunakan thumbnail sampul .NET MAUI eBook.

.NET MAUI menyertakan dukungan untuk navigasi halaman, yang biasanya dihasilkan dari interaksi pengguna dengan UI atau dari aplikasi itu sendiri sebagai akibat dari perubahan status berbasis logika internal. Namun, navigasi dapat rumit untuk diterapkan di aplikasi yang menggunakan pola Model-View-ViewModel (MVVM), karena tantangan berikut harus dipenuhi:

  • Mengidentifikasi tampilan yang akan dinavigasi untuk menggunakan pendekatan yang tidak memperkenalkan kopling dan dependensi yang ketat di antara tampilan.
  • Mengoordinasikan proses di mana tampilan yang akan dinavigasi dibuat dan diinisialisasi. Saat menggunakan MVVM, tampilan dan model tampilan perlu dibuat dan dikaitkan satu sama lain melalui konteks pengikatan tampilan. Saat aplikasi menggunakan kontainer injeksi dependensi, instansiasi tampilan dan model tampilan mungkin memerlukan mekanisme konstruksi tertentu.
  • Apakah akan melakukan navigasi view-first, atau navigasi view-model-first. Dengan navigasi tampilan-pertama, halaman untuk menavigasi untuk merujuk ke nama jenis tampilan. Selama navigasi, tampilan yang ditentukan dibuat, bersama dengan model tampilan yang sesuai dan layanan dependen lainnya. Pendekatan alternatif adalah menggunakan navigasi view-model-first, di mana halaman untuk menavigasi merujuk ke nama jenis model tampilan.
  • Menentukan cara memisahkan perilaku navigasi aplikasi dengan bersih di seluruh tampilan dan model tampilan. Pola MVVM memisahkan UI aplikasi dan logika presentasi dan bisnisnya, tetapi tidak menyediakan mekanisme langsung untuk mengikatnya bersama-sama. Namun, perilaku navigasi aplikasi akan sering menjangkau UI dan bagian presentasi aplikasi. Pengguna akan sering memulai navigasi dari tampilan, dan tampilan akan diganti sebagai akibat dari navigasi. Namun, navigasi mungkin sering juga perlu dimulai atau dikoordinasikan dari dalam model tampilan.
  • Menentukan cara meneruskan parameter selama navigasi untuk tujuan inisialisasi. Misalnya, jika pengguna menavigasi ke tampilan untuk memperbarui detail pesanan, data pesanan harus diteruskan ke tampilan sehingga dapat menampilkan data yang benar.
  • Navigasi koordinasi untuk memastikan bahwa aturan bisnis tertentu dipatuhi. Misalnya, pengguna mungkin diminta sebelum menavigasi jauh dari tampilan sehingga mereka dapat memperbaiki data yang tidak valid atau diminta untuk mengirimkan atau membuang perubahan data apa pun yang dibuat dalam tampilan.

Bab ini membahas tantangan ini dengan menyajikan kelas layanan navigasi bernama MauiNavigationService yang digunakan untuk melakukan navigasi halaman view-model-first.

Catatan

Aplikasi MauiNavigationService yang digunakan sederhana dan tidak mencakup semua jenis navigasi yang mungkin. Jenis navigasi yang diperlukan oleh aplikasi Anda mungkin memerlukan fungsionalitas tambahan.

Logika navigasi dapat berada di tampilan kode belakang atau model tampilan terikat data. Meskipun menempatkan logika navigasi dalam tampilan mungkin merupakan pendekatan yang paling mudah, itu tidak mudah diuji melalui pengujian unit. Menempatkan logika navigasi dalam kelas model tampilan berarti bahwa logika dapat diverifikasi melalui pengujian unit. Selain itu, model tampilan kemudian dapat menerapkan logika untuk mengontrol navigasi untuk memastikan bahwa aturan bisnis tertentu diberlakukan. Misalnya, aplikasi mungkin tidak mengizinkan pengguna untuk menavigasi jauh dari halaman tanpa terlebih dahulu memastikan bahwa data yang dimasukkan valid.

Layanan navigasi biasanya dipanggil dari model tampilan, untuk mempromosikan uji coba. Namun, menavigasi ke tampilan dari model tampilan akan mengharuskan model tampilan untuk mereferensikan tampilan, dan terutama melihat bahwa model tampilan aktif tidak terkait dengan, yang tidak disarankan. Oleh karena itu, yang MauiNavigationService disajikan di sini menentukan jenis model tampilan sebagai target untuk dinavigasi.

Aplikasi multi-platform eShop menggunakan MauiNavigationService kelas untuk menyediakan navigasi view-model-first. Kelas ini mengimplementasikan INavigationService antarmuka, yang ditunjukkan dalam contoh kode berikut:

public interface INavigationService
{
    Task InitializeAsync();

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

    Task PopAsync();
}

Antarmuka ini menentukan bahwa kelas penerapan harus menyediakan metode berikut:

Metode Tujuan
InitializeAsync Melakukan navigasi ke salah satu dari dua halaman saat aplikasi diluncurkan.
NavigateToAsync(string route, IDictionary<string, object> routeParameters = null) Melakukan navigasi hierarkis ke halaman tertentu menggunakan rute navigasi terdaftar. Dapat secara opsional meneruskan parameter rute bernama yang akan digunakan untuk diproses di halaman tujuan
PopAsync Menghapus halaman saat ini dari tumpukan navigasi.

Catatan

Antarmuka INavigationService biasanya juga akan menentukan GoBackAsync metode, yang digunakan untuk kembali secara terprogram ke halaman sebelumnya di tumpukan navigasi. Namun, metode ini hilang dari aplikasi multi-platform eShop karena tidak diperlukan.

Membuat instans MauiNavigationService

Kelas MauiNavigationService , yang mengimplementasikan INavigationService antarmuka, terdaftar sebagai singleton dengan kontainer injeksi dependensi dalam MauiProgram.CreateMauiApp() metode , seperti yang ditunjukkan dalam contoh kode berikut:

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

Antarmuka INavigationService kemudian dapat diselesaikan dengan menambahkannya ke konstruktor tampilan dan model tampilan kami, seperti yang ditunjukkan dalam contoh kode berikut:

public AppShell(INavigationService navigationService)

Ini mengembalikan referensi ke MauiNavigationService objek yang disimpan dalam kontainer injeksi dependensi.

Kelas ViewModelBase menyimpan instans MauiNavigationService dalam NavigationService properti, dari jenis INavigationService. Oleh karena itu, semua kelas model tampilan, yang berasal dari ViewModelBase kelas, dapat menggunakan NavigationService properti untuk mengakses metode yang ditentukan oleh INavigationService antarmuka.

Menangani permintaan navigasi

.NET MAUI menyediakan beberapa cara untuk menavigasi dalam aplikasi. Cara tradisional untuk menavigasi adalah dengan NavigationPage kelas , yang mengimplementasikan pengalaman navigasi hierarkis di mana pengguna dapat menavigasi melalui halaman, maju dan mundur, seperti yang diinginkan. Aplikasi eShop menggunakan Shell komponen sebagai kontainer akar untuk aplikasi dan sebagai host navigasi. Untuk informasi selengkapnya tentang navigasi Shell, lihat Navigasi Shell di Pusat Pengembang Microsoft.

Navigasi dilakukan di dalam kelas model tampilan dengan memanggil salah NavigateToAsync satu metode, menentukan jalur rute untuk halaman yang dinavigasi, seperti yang ditunjukkan dalam contoh kode berikut:

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

Contoh kode berikut menunjukkan metode yang NavigateToAsync disediakan oleh MauiNavigationService kelas:

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

Kontrol .NET MAUIShell sudah terbiasa dengan navigasi berbasis rute, sehingga NavigateToAsync metode ini berfungsi untuk menutupi fungsionalitas ini. Metode ini NavigateToAsync memungkinkan data navigasi ditentukan sebagai argumen yang diteruskan ke model tampilan yang dinavigasi, di mana biasanya digunakan untuk melakukan inisialisasi. Untuk informasi selengkapnya, lihat Meneruskan parameter selama navigasi.

Penting

Ada beberapa cara untuk melakukan navigasi di .NET MAUI. MauiNavigationService secara khusus dibangun untuk bekerja dengan Shell. Jika Anda menggunakan NavigationPage atau TabbedPage atau mekanisme navigasi yang berbeda, layanan perutean ini harus diperbarui untuk bekerja menggunakan komponen tersebut.

Untuk mendaftarkan rute untuk MauiNavigationService kita perlu menyediakan informasi rute dari XAML atau di kode-belakang. Contoh berikut menunjukkan pendaftaran rute melalui 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>

Dalam contoh ini, ShellContent objek antarmuka pengguna dan TabBar mengatur properti mereka Route . Ini adalah metode yang disukai untuk mendaftarkan rute untuk objek antarmuka pengguna yang dikendalikan oleh Shell.

Jika kita memiliki objek yang akan ditambahkan ke tumpukan navigasi di lain waktu, maka kita perlu menambahkannya melalui code-behind. Contoh berikut menunjukkan pendaftaran rute di code-behind.

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

Di code-behind, kita akan memanggil Routing.RegisterRoute metode yang mengambil nama rute sebagai parameter pertama dan jenis tampilan sebagai parameter kedua. Saat model tampilan menggunakan NavigationService properti untuk menavigasi, objek aplikasi Shell akan mencari rute terdaftar dan mendorongnya ke tumpukan navigasi.

Setelah tampilan dibuat dan dinavigasi, ApplyQueryAttributes metode dan InitializeAsync dari model tampilan terkait tampilan dijalankan. Untuk informasi selengkapnya, lihat Meneruskan parameter selama navigasi.

Saat aplikasi diluncurkan, Shell objek diatur sebagai tampilan akar aplikasi. Setelah diatur, Shell akan digunakan untuk mengontrol pendaftaran rute dan akan ada di akar aplikasi kami ke depannya. Shell Setelah dibuat, kita dapat menunggunya dilampirkan ke aplikasi menggunakan OnParentSet metode untuk menginisialisasi rute navigasi kita. Contoh kode berikut menunjukkan metode ini:

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

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

Metode ini menggunakan instans INavigationService yang disediakan konstruktor dari injeksi dependensi dan memanggil metodenya InitializeAsync .

Contoh kode berikut menunjukkan implementasi MauiNavigationService.InitializeAsync metode :

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

Rute //Main/Catalog dinavigasi ke jika aplikasi memiliki token akses cache, yang digunakan untuk autentikasi. Jika tidak, //Login rute akan dinavigasi.

Meneruskan parameter selama navigasi

Metode NavigateToAsync , yang ditentukan oleh INavigationService antarmuka, memungkinkan data navigasi ditentukan sebagai IDictionary<string, object> data yang diteruskan ke model tampilan yang dinavigasi, tempat biasanya digunakan untuk melakukan inisialisasi.

Misalnya, ProfileViewModel kelas berisi OrderDetailCommand yang dijalankan saat pengguna memilih pesanan di ProfileView halaman. Pada gilirannya OrderDetailAsync , ini menjalankan metode , yang ditunjukkan dalam contoh kode berikut:

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

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

Metode ini memanggil navigasi ke OrderDetail rute, meneruskan informasi nomor pesanan urutan yang dipilih pengguna. Ketika kerangka kerja injeksi dependensi membuat OrderDetailView untuk OrderDetail rute bersama dengan OrderDetailViewModel kelas yang ditetapkan ke tampilan BindingContext. OrderDetailViewModel memiliki atribut yang ditambahkan ke dalamnya yang memungkinkannya menerima data dari layanan navigasi seperti yang ditunjukkan pada contoh kode di bawah ini.

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

Atribut memungkinkan QueryProperty kita untuk memberikan parameter untuk properti untuk memetakan nilai ke dan kunci untuk menemukan nilai dari kamus parameter kueri. Dalam contoh ini, kunci "OrderNumber" dan nilai nomor pesanan disediakan selama NavigateToAsync panggilan. Model tampilan menemukan kunci "OrderNumber" dan memetakan nilai ke OrderNumber properti . Properti OrderNumber kemudian dapat digunakan di lain waktu untuk mengambil detail pesanan lengkap dari OrderService instans.

Memanggil navigasi menggunakan perilaku

Navigasi biasanya dipicu dari tampilan oleh interaksi pengguna. Misalnya, LoginView navigasi melakukan setelah autentikasi berhasil. Contoh kode berikut menunjukkan bagaimana navigasi dipanggil oleh perilaku:

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

Pada runtime, EventToCommandBehavior akan merespons interaksi dengan WebView. WebView Ketika menavigasi ke halaman web, Navigating peristiwa akan diaktifkan, yang akan menjalankan NavigateCommand di LoginViewModel. Secara default, argumen peristiwa untuk peristiwa diteruskan ke perintah . Data ini dikonversi karena diteruskan antara sumber dan target oleh pengonversi yang ditentukan dalam EventArgsConverter properti , yang mengembalikan Url dari WebNavigatingEventArgs. Oleh karena itu, ketika NavigationCommand dijalankan, Url halaman web diteruskan sebagai parameter ke Tindakan terdaftar.

Pada gilirannya, menjalankan NavigationCommand NavigateAsync metode , yang ditunjukkan dalam contoh kode berikut:

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

Metode ini memanggil NavigationService rute aplikasi ke //Main/Catalog rute.

Mengonfirmasi atau membatalkan navigasi

Aplikasi mungkin perlu berinteraksi dengan pengguna selama operasi navigasi, sehingga pengguna dapat mengonfirmasi atau membatalkan navigasi. Ini mungkin diperlukan, misalnya, ketika pengguna mencoba menavigasi sebelum menyelesaikan halaman entri data sepenuhnya. Dalam situasi ini, aplikasi harus memberikan pemberitahuan yang memungkinkan pengguna untuk menavigasi jauh dari halaman, atau untuk membatalkan operasi navigasi sebelum terjadi. Ini dapat dicapai dalam kelas model tampilan dengan menggunakan respons dari pemberitahuan untuk mengontrol apakah navigasi dipanggil atau tidak.

Ringkasan

.NET MAUI menyertakan dukungan untuk navigasi halaman, yang biasanya dihasilkan dari interaksi pengguna dengan UI, atau dari aplikasi itu sendiri, sebagai akibat dari perubahan status berbasis logika internal. Namun, navigasi bisa rumit untuk diterapkan di aplikasi yang menggunakan pola MVVM.

Bab ini menyajikan kelas NavigationService, yang digunakan untuk melakukan navigasi view-model-first dari view-models. Menempatkan logika navigasi dalam kelas model tampilan berarti bahwa logika dapat dilakukan melalui pengujian otomatis. Selain itu, model tampilan kemudian dapat menerapkan logika untuk mengontrol navigasi untuk memastikan bahwa aturan bisnis tertentu diberlakukan.