Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
lawrence_shaun_introducing_net_maui_build_and_deploy_crosspl.pdf
Скачиваний:
46
Добавлен:
26.06.2023
Размер:
5.15 Mб
Скачать

Chapter 5 User Interface Essentials

The Route property you will control as part of the next section, “Navigation.”

Finally, you will need to add xmlns:pages="clrnamespace:WidgetBoard.Pages" to the top of the file.

Navigation

I am personally a fan of simplifying the code I write so long as it continues to make it easy to read. With this in mind I would like to suggest you improve on the registration of your pages and their view models already.

Registering Pages for Navigation

Therefore I suggest that you create a new method into your MauiProgram. cs file.

private static IServiceCollection AddPage<TPage, TViewModel>( IServiceCollection services,

string route) where TPage : Page

where TViewModel : BaseViewModel

{

services

.AddTransient(typeof(TPage))

.AddTransient(typeof(TViewModel));

Routing.RegisterRoute(route, typeof(TPage));

return services;

}

Notice the line Routing.RegisterRoute(route, typeof(TView));.

This serves as a very important part in this topic of navigation. It means that when you tell Shell to navigate to a specific route, it will create a new

150

Chapter 5 User Interface Essentials

instance of the TPage type you passed in and navigate to it. Of course, because you have registered these types with the dependency injection layer, it means that any dependencies that are defined as parameters to the constructor will be created and passed in for you.

The above then means that rather than writing

services.AddTransient<BoardDetailsPage>()

services.AddTransient<BoardDetailsPageViewModel>()

Routing.RegisterRoute(route, typeof(TPage));

you can now write

AddPage<BoardDetailsPage, BoardDetailsViewModel>(builder.

Services, "boarddetails");

with the added change that you now define this route. So let’s go and delete your old registrations and replace with

AddPage<BoardDetailsPage, BoardDetailsPageViewModel>(builder.

Services, "boarddetails");

AddPage<FixedBoardPage, FixedBoardPageViewModel>(builder.

Services, "fixedboard");

I also recommend defining the routes as constant strings somewhere in your codebase to avoid typos when wanting to navigate to them.

This means you can save one line of code per page and view model pair that you had registered as well as the code to register the route for navigation.

Now that you have registered your pages, let’s take a look at how you can actually perform navigation.

Performing Navigation

There are multiple ways to specify the route for navigation but they all use the Shell.Current.GoToAsync method.

151

Chapter 5 User Interface Essentials

So, for example, you could navigate to your FixedBoardPage with the following:

await Shell.Current.GoToAsync(“fixedboard”);

This will result in a FixedBoardPage being created and pushed onto the navigation stack. This is precisely the behavior that you need at the end of your SaveCommand execution in your BoardDetailsPagesViewModel class.

Navigating Backwards

You can also pop pages off the navigation stack by navigating backward. This can be achieved by the following:

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

with the .. component telling Shell that it needs to go backward. In fact, backwards and forwards navigation can be performed together:

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

Passing Data When Navigating

One key thing that you really need to do as part of creating your board and navigating to the page that will render the board is to pass the context across to that page so it knows what to render. There are multiple ways to both send the data and also to receive it.

Let’s start with sending.

•\ You can pass primitive data through the query string itself, for example

await Shell.Current.GoToAsync("fixedboard?board id=1234");

152

Chapter 5 User Interface Essentials

By providing the boardid, you put the responsibility on the receiving page (or page view model) to retrieve the right board by using the specified ID.

•\ More complex data can be sent as an

IDictionary<string, object> parameter in the

GoToAsync method, such as

await Shell.Current.GoToAsync( "fixedboard",

new Dictionary<string, object>

{

{ "Board", board}

});

You can also send a complex object like the above, which means the originating page (or page view model) is responsible for retrieving or constructing the board and you send the whole thing to the receiving page.

Then, to receive data, you can implement the IQueryAttributable interface provided with .NET MAUI. Shell will either call this on

the page you are navigating to, or if the BindingContext (your view model) implements the interface, it will call it there. Add this to your FixedBoardPageViewModel class because you are going to need to process the data. You will be going with the complex object option because you have already loaded the Board in your AppShellViewModel class.

public void ApplyQueryAttributes(IDictionary<string, object> query)

{

var board = query["Board"] as Board;

}

153