XAML Based Navigation in Windows and Multi-Platform Applications with Uno.Extensions

One of the more complex parts of building an application is getting navigation to work. In a Windows application (or in a multi-platform application using the Uno Platform) you can easily navigate between pages using Frame.Navigate and Frame.GoBack but what if you want to use a more complex navigation structure like tabs or a NavigationView. Also, what if you want to control navigation from a ViewModel or directly from XAML. In this post we’re going to look at the Navigation pattern in Uno.Extensions and specifically how you can use it to trigger navigation from XAML.

To get started, we’re going to use the Uno Platform Visual Studio Wizard to create a new application that already has Uno.Extensions referenced and setup. If you have an existing project, whether it be a WinUI/WinAppSdk based application, or an Uno Platform application, you can add references to Uno.Extensions.Navigation.WinUI and follow the documentation on adding Hosting to your application. After adding hosting, you’ll need to use the UseNavigation extension method on the IHostBuilder to connect up navigation.

Using the wizard, we’re going to select the Blank configuration and then click the Customize button.

In the Extensions section, we’ll enable Dependency Injection (this wires up the IHostBuilder and the dependency injection container that’s required for Uno.Extensions navigation to work) and then set Navigation to use Regions.

Even though we selected the Blank configuration, because we subsequently enabled Region based navigation, the generated application already comes with two pages, MainPage and SecondPage. However, navigation from MainPage to SecondPage is done in c# code in the MainViewModel.

private async Task GoToSecondView()
{
    await _navigator.NavigateViewModelAsync<SecondViewModel>(this, data: new Entity(Name!));
}

We’re going to change this to trigger navigation in XAML by replacing the Command attribute with Navigation.Request.

<Button Content="Go to Second Page"
		uen:Navigation.Request="Second" />

This is sufficient to navigation to SecondPage when the Button is clicked. You might be wondering where the “Second” request is defined. The answer to this is that it’s configured as part of the IHostBuilder setup, which can be found in the RegisterRoute method in App.cs.

private static void RegisterRoutes(IViewRegistry views, IRouteRegistry routes)
{
    views.Register(
        new ViewMap(ViewModel: typeof(ShellViewModel)),
        new ViewMap<MainPage, MainViewModel>(),
        new DataViewMap<SecondPage, SecondViewModel, Entity>()
    );

    routes.Register(
        new RouteMap("", View: views.FindByViewModel<ShellViewModel>(),
            Nested: new RouteMap[]
            {
            new RouteMap("Main", View: views.FindByViewModel<MainViewModel>()),
            new RouteMap("Second", View: views.FindByViewModel<SecondViewModel>()),
            }
        )
    );
}

XAML based navigation eliminates the need for code in either the codebehind files, or the corresponding viewmodel, for navigating between pages. You can either send (and receive) data with navigation using the Navigation.Data attached property (see documentation for more information)

1 thought on “XAML Based Navigation in Windows and Multi-Platform Applications with Uno.Extensions”

Leave a comment