HomeAbout Me

Componentizer4k - In-Page Navigation for .NET MAUI

By Michael Stonis
Published in Development
July 14, 2024
Componentizer4k - In-Page Navigation for .NET MAUI

Componentizer4k - In-Page Navigation for .NET MAUI

Overview

When building a workflow for a mobile application, it’s not uncommon to need to be able to go through a multi-step process. In .NET MAUI, I often see people use something like the CarouselView control to switch between these components. While that works, it becomes cumbersome because the carousel control is intended for use where you have an indefinite amount of similar items. If you need to manage multiple controls where each control has a unique view model, that is where the Componentizer shines. You can think of it as an in-page way to navigate between subcomponents or workflows of your page with familiar APIs and MVVM-focused features.

Library

NuGet

Source Code

GitHub

Solution

This is a simple component that offers up the following features:

  • In-Page Navigation Easily navigate within a single page, updating content dynamically.

  • Multiple Navigation Methods Navigate between different components from your views or use view models with simple registration.

  • Easy Testing Everything is backed by interfaces, so you can unit test your little heart out.

  • Simplified API A clean and intuitive API for handling navigation within your app.

Usage

Registration

The Componentizer uses a view model-first configuration that needs a view model to be registered to a view. This is done in the MauiProgram using the RegisterComponents extension method.

⚠️ NOTE
Componentizer uses dependency injection to create your view models and views, so make sure that you register them using the builder’s Services collection.

Below is an example of registering your views and view models.

public static class MauiProgram
{
public static MauiApp CreateMauiApp()
{
MauiAppBuilder builder = MauiApp.CreateBuilder();
builder
.UseMauiApp<App>()
.ConfigureFonts(
fonts =>
{
fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
})
.RegisterViews()
.RegisterViewModels()
.RegisterComponents(
componentNavigation =>
{
componentNavigation.RegisterView<SampleAViewModel, ComponentA>();
componentNavigation.RegisterView<SampleBViewModel, ComponentB>();
})
.Build();
}
private static MauiAppBuilder RegisterViews(this MauiAppBuilder builder)
{
builder.Services.AddTransient<MainPage>();
builder.Services.AddTransient<ComponentA>();
builder.Services.AddTransient<ComponentB>();
return builder;
}
private static MauiAppBuilder RegisterViewModels(this MauiAppBuilder builder)
{
builder.Services.AddTransient<MainViewModel>();
builder.Services.AddTransient<SampleAViewModel>();
builder.Services.AddTransient<SampleBViewModel>();
return builder;
}
}

Page Configuration

The first thing to do is import the namespace for the control using the http://componentizer.4k/schemas/controls namespace.

<ContentPage
x:Class="SampleApp.MainPage"
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:ctz="http://componentizer.4k/schemas/controls">
...
</ContentPage>

Once configured, you can add a MauiComponentNavigator control to your user interface. The MauiComponentNavigator is a container control that will host your views. The only other required property is ComponentName, a unique identifier for this specific component. The ComponentName property will need to be referenced from your view model layer, so it is recommended to host this with a shared reference or to keep track of the name as you will need it later on. One of the neat parts of component navigation is that you can host multiple MauiComponentNavigator components on a single page.

<ctz:MauiComponentNavigator
x:Name="ComponentNav"
ComponentName="{x:Static local:ComponentNames.MainComponent}" />

To perform the actual navigation, you will need to get an instance of the IComponentNavigation component. This is registered with the dependency injection container as a singleton, so it can either be resolved using the service provider or via dependency injection. IComponentNavigation has a very similar API to MAUI’s stack-based INavigation manager where you can choose to PushAsync and ‘PopAsync’, but it requires the view model and component that you will be navigating to.

In this example, the _componentNavigation instance will push a new instance of the SampleAViewModel associated with the ComponentA in the RegisterComponents method. The view will be pushed to the container named MainComponent. As stated earlier, it is recommended to place the names of your components in shared code so that the views and the view models can reference them without a direct dependency between them.

await _componentNavigation.PushAsync<SampleAViewModel>(ComponentNames.MainComponent);

The IComponentNavigation allows you to pass an optional Dictionary<string, object> query parameter. If your View or view model implements the IQueryAttributable interface, the query dictionary will be passed

await this._componentNavigation.PushAsync<SampleBViewModel>(
ComponentNames.MainComponent,
new Dictionary<string, object>
{
{ "Value", DateTimeOffset.Now.ToUnixTimeMilliseconds() },
});

Tags

#dotnet#dotnet_maui#maui

Share

Previous Article
What is This Sheet? A Bottom Sheet for MAUI

Quick Links

Eight-BotAbout Me

Social Media