.Net MAUI /First Look #2

Introduction by Microsoft
This cannot be done better than by the original creators at Microsoft:
- Navigating Between Pages in .NET MAUI [6 of 8]
- Accessing Platform Features in .NET MAUI [7 of 8]
- .NET MAUI Resources & Beginner Series Recap [8 of 8]
Lessons learned
Navigation from page to page in C# Net Maui is a bigger issue woth disuccing, Although it can be done with little code. On this page I'll only cover navigation, since it takes up a lot of space for examples.
Application Navigation
Maui uses routes to navigate between pages. That's the reason we'll define routes to every page and add navigation between them.
New associated Objects
First create a page and a viewmodel. Let's call the page DetailPage
and the viewmodel DetailViewModel.cs
. Behold the pattern here: Always use (Detail|[Page|ViewModel]) as a convention to know they are related. We'll again use the CommunityToolkit
to simplify some property generation. Make the DetailViewModel
partial
and extend from ObservableObject
. Finally pass the ViewModel via the constructor like so:
using MauiTest.ViewModel;
namespace MauiTest;
public partial class DetailPage : ContentPage
{
public DetailPage(DetailViewModel vm)
{
InitializeComponent();
BindingContext = vm;
}
}
The new classes must be registered in out CreateMauiApp()
Method. Keep in mind that this time we make the page transient (AddTransient
) so it gets created every time we navigate here. The following code describes just that:
builder.Services.AddTransient<DetailPage>();
builder.Services.AddTransient<DetailViewModel>();
Routing Mechanism
Behold the standard App route points to the MainPage
class. So this is the route that opens by default. Other routing options are not registered, yet.
<?xml version="1.0" encoding="UTF-8" ?>
<Shell
x:Class="MauiTest.AppShell"
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:MauiTest"
Shell.FlyoutBehavior="Disabled">
<ShellContent
Title="Home"
ContentTemplate="{DataTemplate local:MainPage}"
Route="MainPage" />
</Shell>
Use the AppShell
to add a new route. This way our application knows with which class a route is associated. Use any key you like but it easier to use the classname or a set of certain keys. We'll use the class name here to identify the route.
namespace MauiTest;
public partial class AppShell : Shell
{
public AppShell()
{
InitializeComponent();
// The name can be anything but it makes sense to use the object name
Routing.RegisterRoute(nameof(DetailPage), typeof(DetailPage));
}
}
UI Interaction and Navigation
There are plenty of gesture recognizers. We wanna use a TapGestureRecognizer
which can simply be connected to a command. Just extend the XAML syntax that displays the bound Text
property. Connect it to the Command on the BindingContext (which should be the ViewModel).
<Grid
Padding="0,5">
<Frame
Background="White"
CornerRadius="5">
<Frame.GestureRecognizers>
<TapGestureRecognizer
Command="{Binding Source={RelativeSource AncestorType={x:Type vm:MainViewModel}}, Path=TapCommand}"
CommandParameter="{Binding .}" />
</Frame.GestureRecognizers>
<Label
TextColor="Black"
Text="{Binding .}"
FontSize="24" />
</Frame>
</Grid>
The Command implementation will look like this, since we have used the classname as route identifier. The [RelayCommand]
will also generate a bindable command for us.
[RelayCommand]
async Task Tap(string s)
{
// Navigate to the other page via its name
await Shell.Current.GoToAsync(nameof(DetailPage));
}
We can now navigate to the new page. Navigating back works similar to navigating through a filesaystem. For example ".."
navigates back one page. Combine these with other pages that you want to navigate to. If for example you would wanna go back and then to a page that's called Export you could navigate to: "../Export"
. So to just go back we navigate to:
[RelayCommand]
async Task GoBack()
{
await Shell.Current.GoToAsync("..");
}
Sending parameters
Just navigating somewhere sometimes doesn't cut it. We might also need to pass along some parameters. Behold the following example, where a parameter Text
is passed along., where s
is a string
variable.
await Shell.Current.GoToAsync($"{nameof(DetailPage)}?TextVal={s}");
To pass along complex datatypes we'll use an extra dictionary like so:
await Shell.Current.GoToAsync($"{nameof(DetailPage)}?TextVal={s}",
new Dictionary<string, object>
{
{"key1", obj1},
{"key2", obj2},
...
});
The model must receive declarations associating parameters and member variables. Heading over to the ViewModel
we can now mark it with QueryProperty
. This way we'll know which parameters are supposed to be sent to which class properties.
[QueryProperty("Text", "TextVal")]
public partial class DetailViewModel : ObservableObject
{
public string Text { get; set; }
}
Links & Resources
- YouTube Video Introduction Series of Videos by Microsoft to introduce .Net MAUI
- Sample Code The code for the sample app we're programming here
- Aloha Kit There is an experimental project in .NET called Microsoft.Maui.Graphics.Controls (GraphicsControls) with drawn controls. The main goal of GraphicsControls is to validate if there are interest in .NET MAUI drawn controls, creating the controls that were available in Xamarin.Forms Visual with Cupertino, Fluent and Material Design.
- Awesome .Net Maui .NET Multi-platform App UI (.NET MAUI) is a cross-platform framework for creating native mobile and desktop apps with C# and XAML. Using .NET MAUI, you can develop apps that can run on Android, iOS, macOS, and Windows from a single shared code-base.