How-To: Navigate Between Pages
This topic covers using Navigation to navigate between two pages using frame-based navigation.
Note
This guide uses predefined code created by the Uno Template using the Recommended preset, however, it uses the MVVM approach for the examples instead of MVUX defined in the Recommended preset.
Step-by-step
Important
This guide assumes you used the template wizard or dotnet new unoapp to create your solution. If not, it is recommended that you follow the Creating an application with Uno.Extensions documentation to create an application from the template.
1. Installation
Add
Navigationto the<UnoFeatures>property in the Class Library (.csproj) file.<UnoFeatures> Material; Extensions; + Navigation; Toolkit; MVUX; </UnoFeatures>
2. Navigating to a New Page
Add a new
Pageto navigate to,SamplePage.xamlIn
MainPage.xamlreplace the existingButtonwith the following XAML, which includes a handler for the Click event<Button Content="Go to SamplePage" Click="GoToSamplePageClick" />In the
GoToSamplePageClickmethod, use theNavigatorextension method to get a reference to anINavigatorinstance and callNavigateViewAsyncto navigate to theSamplePage. This will push a new instance of theSamplePageonto the current Frame, pushing theMainPageto the back-stack.private void GoToSamplePageClick(object sender, RoutedEventArgs e) { _ = this.Navigator()?.NavigateViewAsync<SamplePage>(this); }
3. Navigating Back to the Previous Page
In
SamplePage.xamladd aButtonwith a handler for theClickevent<Button Content="Go Back" Click="GoBackClick" />Again, use the
Navigatorextension method to access theINavigatorinstance and callNavigateBackAsync. This will cause the frame to navigate to the previous page on the back-stack and releasing theSamplePageinstance.private void GoBackClick(object sender, RoutedEventArgs e) { _ = this.Navigator()?.NavigateBackAsync(this); }
4. Defining ViewMap and RouteMap
At this point, if you inspect the Output window you'll see a line that says something similar to:
For better performance (avoid reflection), create a mapping for for path 'Sample', view 'SamplePage', view model
This warning exists because Navigation uses reflection as a fallback mechanism to associate types and the corresponding navigation route. This can be resolved by specifying a ViewMap and a RouteMap for the SamplePage to eliminate the need for reflection
Update the
RegisterRoutesmethod in theApp.xaml.csfileprivate static void RegisterRoutes(IViewRegistry views, IRouteRegistry routes) { views.Register( new ViewMap(ViewModel: typeof(ShellViewModel)), new ViewMap<MainPage, MainViewModel>(), new DataViewMap<SecondPage, SecondViewModel, Entity>(), new ViewMap<SamplePage>() ); routes.Register( new RouteMap("", View: views.FindByViewModel<ShellViewModel>(), Nested: [ new ("Main", View: views.FindByViewModel<MainViewModel>()), new ("Second", View: views.FindByViewModel<SecondViewModel>()), new ("Sample", View: views.FindByView<SamplePage>()), ] ) ); }
5. Associating a View Model
By defining a ViewMap that associates a view with a view model, an instance of the view model can dynamically be created and is subsequently set as the DataContext on the view that's navigated to.
Create a new class
SampleViewModelin the Presentation folderpublic class SampleViewModel { public string Title => "Sample Page"; public SampleViewModel() { } }Update
ViewMapinApp.xaml.csto includeSampleViewModelnew ViewMap<SamplePage, SampleViewModel>()Add
TextBlockto theSamplePage.xamland data bind to theTitleproperty<TextBlock Text="{Binding Title}" />
6. Navigating via View Models
The Navigation code can be moved from the SamplePage.cs code-behind file to the SampleViewModel.
Update
SampleViewModelto take a constructor dependency onINavigatorand add aGoBackmethod that will call theNavigateBackAsyncmethodprivate readonly INavigator _navigator; public SampleViewModel(INavigator navigator) { _navigator = navigator; } public Task GoBack() { return _navigator.NavigateBackAsync(this); }In order to use
x:Bindto invoke theGoBackmethod on theSampleViewModeltheSamplePageneeds to expose a property that returns theDataContextas aSampleViewModel.public SampleViewModel? ViewModel => DataContext as SampleViewModel; public SamplePage() { this.InitializeComponent(); }Update the
ButtoninSamplePage.xamlto set theClickmethod tox:Bindto theGoBackmethod<Button Content="Go Back (View Model)" Click="{x:Bind ViewModel.GoBack}" />