How-To: Use a NavigationView to Switch Views
Choosing the right control for your navigation needs is important, and one common choice is NavigationView. This control adapts to different screen sizes and offers a uniform top-level navigation experience. NavigationView is a great option for adaptive, customizable, and mobile-friendly navigation. The Uno Platform extensions for navigation provide built-in support for using NavigationView and NavigationViewItem to switch between views. This tutorial will show you how to configure a NavigationView for use with the navigation extensions.
Step-by-steps
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 instructions for creating an application from the template.
1. Add XAML namespace mapping
Add the following namespace mapping to the root element of your XAML page:
xmlns:uen="using:Uno.Extensions.Navigation.UI"
2. Define the view's layout
Add a
Gridelement to the root of your XAML page. This will be the container for theNavigationViewand the content area.<Grid> ... </Grid>Add a
RowDefinitionto theGrid'sRowDefinitionscollection. This will define the height of theNavigationView's menu.<Grid.RowDefinitions> <RowDefinition Height="Auto" /> <RowDefinition /> </Grid.RowDefinitions>Add a
NavigationViewcontrol to theGrid. This will be the menu for the app.<NavigationView Grid.Row="1"> ... </NavigationView>Add a
Gridelement to the control.NavigationViewcontains two sections for content:- A pane which contains a list of navigation
MenuItems - The content area intended to correspond with the selected
NavigationViewItem.
For this tutorial,
Gridshould be placed in theContentarea.<Grid Grid.Row="1"> ... </Grid>- A pane which contains a list of navigation
3. Add the navigation view items
Add the
NavigationView.MenuItemscollection to theNavigationViewand add aNavigationViewItemfor each view you want to navigate to.<NavigationView.MenuItems> <NavigationViewItem Content="One" /> <NavigationViewItem Content="Two" /> <NavigationViewItem Content="Three" /> </NavigationView.MenuItems>
4. Add the navigation view content
Inside the
Gridelement of theNavigationView, add aGridelement to represent the content of each view you can to navigate to.<Grid Grid.Row="1"> <Grid> <TextBlock Text="One" FontSize="24" HorizontalAlignment="Center" VerticalAlignment="Center" /> </Grid> <Grid> <TextBlock Text="Two" FontSize="24" HorizontalAlignment="Center" VerticalAlignment="Center" /> </Grid> <Grid> <TextBlock Text="Three" FontSize="24" HorizontalAlignment="Center" VerticalAlignment="Center" /> </Grid> </Grid>
5. Set up navigation
Components with navigation enabled will have their visual trees considered by the navigation service when a request is made. The matching region will be shown and the rest will be hidden.
Add the
uen:Region.Attachedattached property to each of the following elements:- The
Gridelement that contains theNavigationViewand theGridelement that contains the content area. - The
NavigationViewelement. - The
Gridelement that contains the content area.
uen:Region.Attached="True"- The
Setting this to
Truewill enable the navigation extensions for the element.Add the
uen:Region.Nameattached property to each of theNavigationViewItemelements. This will define the name of the view that theNavigationViewItemwill navigate to.uen:Region.Name="One"The full code for the
NavigationViewItemelements should look like the code example below:<NavigationView.MenuItems> <NavigationViewItem Content="One" uen:Region.Name="One" /> ... </NavigationView.MenuItems>Add the
uen:Region.Navigatorattached property to theGridelement that contains the content area. This will set the type of navigation to adjust the visibility of the content area's children.uen:Region.Navigator="Visibility"Add the
uen:Region.Nameattached property to each of theGridelements that contain the content area. This will define the name of the view that theGridwill represent.uen:Region.Name="One"The full code for the
Gridelements should look like the code example below:<Grid uen:Region.Name="One" Visibility="Collapsed"> <TextBlock Text="One" FontSize="24" HorizontalAlignment="Center" VerticalAlignment="Center" /> </Grid> <Grid uen:Region.Name="Two" Visibility="Collapsed"> <TextBlock Text="Two" FontSize="24" HorizontalAlignment="Center" VerticalAlignment="Center" /> </Grid> <Grid uen:Region.Name="Three" Visibility="Collapsed"> <TextBlock Text="Three" FontSize="24" HorizontalAlignment="Center" VerticalAlignment="Center" /> </Grid>Set the
Visibilityof theGridelements toCollapsedto hide the content area's children beforehand:Visibility="Collapsed"
Navigating to Page elements
You may want to navigate to a
Pageview element represented by a route name. It is possible to do this without defining the view element alongside the other content areas. For instance, you may need to display a products pageProductsPagewhich will be defined in a separate XAML file.Add a new Page item to your app called
ProductsPagewith the following code:<Page x:Class="UsingNavigationView.Views.ProductsPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:Uno.Extensions.Navigation.UI.Samples" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"> <Grid> <TextBlock Text="Products" FontSize="24" HorizontalAlignment="Center" VerticalAlignment="Center" /> </Grid> </Page>For the purposes for this tutorial,
ProductsPagewill be associated with its own view modelProductsViewModel. Add a new Class item to your app calledProductsViewModelwith the following code:namespace UsingNavigationView.ViewModels; public class ProductsViewModel { public ProductsViewModel() { } }Register
ViewMapandRouteMapinstances inside theRegisterRoutesmethod inApp.cs. This associates theProductsPagedescribed above withProductsViewModel, as well as avoiding the use of reflection for route discovery.private static void RegisterRoutes(IViewRegistry views, IRouteRegistry routes) { views.Register( new ViewMap<ShellControl, ShellViewModel>(), new ViewMap<ProductsPage, ProductsViewModel>(), new ViewMap<MainPage, MainViewModel>() ); routes.Register( new RouteMap("", View: views.FindByViewModel<ShellViewModel>(), Nested: new RouteMap[] { new RouteMap("Main", View: views.FindByViewModel<MainViewModel>(), Nested: new RouteMap[] { new RouteMap("Products", View: views.FindByViewModel<ProductsViewModel>()) }) })); }Importantly, the snippet above establishes a route name
ProductsforProductsPage. We can use this route name to navigate to theProductsPageview element.Add a
NavigationViewItemto theNavigationViewelement with theuen:Region.Nameattached property set toProducts.<NavigationView.MenuItems> <NavigationViewItem Content="One" uen:Region.Name="One" /> <NavigationViewItem Content="Two" uen:Region.Name="Two" /> <NavigationViewItem Content="Three" uen:Region.Name="Three" /> <!-- Adds a products item --> <NavigationViewItem Content="Products" uen:Region.Name="Products" /> </NavigationView.MenuItems>
6. Putting it all together
Observe how the
NavigationViewand the content area are now connected. When you select aNavigationViewItem, the correspondingGridorPagewill be shown.If the route name specified represents a
Pageelement, aFramewill be created upon navigation to host thePageelement. ThisFramewill be added to the visual tree in order to support subsequent navigation to otherPageelements.Because the navigation service maintains an instance of the view, users can leave this new
ProductsPageto view item details and return to it without losing any state such as a product filter they have already specified.Now, you have written a UI layout capable of navigating to views with
NavigationView. Your completedMainPage.xamlshould look like the code example below.
Code example
<Page x:Class="UsingNavigationView.Views.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
xmlns:uen="using:Uno.Extensions.Navigation.UI"
Background="{ThemeResource MaterialBackgroundBrush}">
<Grid uen:Region.Attached="True">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition />
</Grid.RowDefinitions>
<NavigationView uen:Region.Attached="true"
Grid.Row="1">
<NavigationView.MenuItems>
<NavigationViewItem Content="One"
uen:Region.Name="One" />
<NavigationViewItem Content="Two"
uen:Region.Name="Two" />
<NavigationViewItem Content="Three"
uen:Region.Name="Three" />
<NavigationViewItem Content="Products"
uen:Region.Name="Products" />
</NavigationView.MenuItems>
<Grid uen:Region.Attached="True"
uen:Region.Navigator="Visibility"
Grid.Row="1">
<Grid uen:Region.Name="One"
Visibility="Collapsed">
<TextBlock Text="One"
FontSize="24"
HorizontalAlignment="Center"
VerticalAlignment="Center" />
</Grid>
<Grid uen:Region.Name="Two"
Visibility="Collapsed">
<TextBlock Text="Two"
FontSize="24"
HorizontalAlignment="Center"
VerticalAlignment="Center" />
</Grid>
<Grid uen:Region.Name="Three"
Visibility="Collapsed">
<TextBlock Text="Three"
FontSize="24"
HorizontalAlignment="Center"
VerticalAlignment="Center" />
</Grid>
</Grid>
</NavigationView>
</Grid>
</Page>