Skip to content
This repository has been archived by the owner on Feb 16, 2022. It is now read-only.

Latest commit

 

History

History
243 lines (180 loc) · 11.1 KB

navigationpane.md

File metadata and controls

243 lines (180 loc) · 11.1 KB

Navigation Pane

❗ There is also a version of this document with code samples in VB.Net

The navigation pane project type includes a navigation menu displayed in a panel at the side of the screen and which can be expanded with the Hamburger icon.

This document covers:

To update to Win UI Navigation View from Hamburger Menu read the following document.

To update to Win UI Navigation View from Navigation View read the following document.

Modifying the menu items

The menu can be modified in the following ways.

  • Change the icon for an NavigationViewItem in the menu.
  • Change the text for an NavigationViewItem in the menu.

Change the icon for an item

By default every NavigationViewItem is displayed with the symbol for a document. When every item has the same icon it is hard to differentiate between them when the NavigationView is collapsed. In almost all cases you will want to change the icon used.

Screenshot of app with different menu icons

Navigate to Views/ShellPage.xaml and change the NavigationViewItems in the NavigationView MenuItems property.

The code below shows the symbols used to create the app shown in the image above.

<winui:NavigationView.MenuItems>
    <!--
    TODO WTS: Change the symbols for each item as appropriate for your app
    More on Segoe UI Symbol icons: https://docs.microsoft.com/windows/uwp/style/segoe-ui-symbol-font
    Or to use an IconElement instead of a Symbol see https://github.com/Microsoft/WindowsTemplateStudio/blob/release/docs/projectTypes/navigationpane.md
    Edit String/en-US/Resources.resw: Add a menu item title for each page
    -->
    <winui:NavigationViewItem x:Uid="Shell_Main" Icon="Home" helpers:NavHelper.NavigateTo="views:MainPage" />
    <winui:NavigationViewItem x:Uid="Shell_Map" Icon="Map" helpers:NavHelper.NavigateTo="views:MapPage" />
    <winui:NavigationViewItem x:Uid="Shell_ListDetails" Icon="DockLeft" helpers:NavHelper.NavigateTo="views:ListDetailsPage" />
    <winui:NavigationViewItem x:Uid="Shell_Tabbed" Icon="Document" helpers:NavHelper.NavigateTo="views:TabbedPage" />
    <winui:NavigationViewItem x:Uid="Shell_WebView" Icon="Globe" helpers:NavHelper.NavigateTo="views:WebViewPage" />
</winui:NavigationView.MenuItems>

The icons are created using the Windows.UI.Xaml.Controls.Symbol enumeration. You can view all the symbols available at https://docs.microsoft.com/uwp/api/windows.ui.xaml.controls.symbol

You can also set the menu item to use an IconElement directly. Like this:

<winui:NavigationView.MenuItems>
    <winui:NavigationViewItem x:Uid="Shell_Main" helpers:NavHelper.NavigateTo="views:MainPage">
        <winui:NavigationViewItem.Icon>
            <FontIcon FontFamily="Segoe MDL2 Assets" Glyph="&#xE707;" />
        </winui:NavigationViewItem.Icon>
    </winui:NavigationViewItem>
</winui:NavigationView.MenuItems>

Change the text for an item

The text for a shell navigation item comes from the localized string resources. For an item which defines the x:Uid Shell_Main the value Shell_Main.Content corresponds with an entry in Resources.resw. Change the value in the resources file to alter what is displayed in the NavigationView.

NavigationViewHeaderBehavior

The navigation pane projects add a Behavior to the NavigationView that allows different pages to customize or hide the Header when that page is shown.

Initial Configuration

The NavigationViewHeaderBehavior includes two properties, DefaultHeader and DefaultHeaderTemplate that will define the content and layout of NavigationView Header by default.

<behaviors:NavigationViewHeaderBehavior
    DefaultHeader="{x:Bind ViewModel.Selected.Content, Mode=OneWay}">
    <behaviors:NavigationViewHeaderBehavior.DefaultHeaderTemplate>
        <DataTemplate>
            <Grid>
                <TextBlock
                    Text="{Binding}"
                    Style="{ThemeResource TitleTextBlockStyle}"
                    Margin="{StaticResource SmallLeftRightMargin}" />
            </Grid>
        </DataTemplate>
    </behaviors:NavigationViewHeaderBehavior.DefaultHeaderTemplate>
</behaviors:NavigationViewHeaderBehavior>

Each page can overwrite three properties of the NavigationViewHeaderBehavior:

  • HeaderMode: allows you to choose when to display the Header on that page (Always, Minimal,Never), Always is the default value.
  • HeaderContext: contains the data that will be available for use from the HeaderTemplate.
  • HeaderTemplate: DataTemplate that personalizes the layout of the header.

HeaderMode="Never" allows the page to hide the Header and occupy the whole window. You can see an example of how to use HeaderMode="Never" in the MapPage. If you use this mode the NavigationView Buttons will overlap with your content in small window sizes.

HeaderMode="Minimal" allows the page to hide the Header and occupy the entire window, except when the NavigationView hides the navigation pane, with a window width less than 641px. This mode avoids overlapping of Navigation View buttons with the content. You can see an example of how to use HeaderMode="Minimal" in WebViewPage.

In the following example, we'll see how to modify the Header in a MainPage in order to add a CommandBar.

<Page
    x:Class="YourAppName.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"
    xmlns:behaviors="using:YourAppName.Behaviors"
    xmlns:viewModels="using:YourAppName.ViewModels"
    Style="{StaticResource PageStyle}"
    mc:Ignorable="d">

    <behaviors:NavigationViewHeaderBehavior.HeaderTemplate>
        <DataTemplate x:DataType="viewModels:MainViewModel">
            <CommandBar
                Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
                Foreground="{ThemeResource ApplicationForegroundThemeBrush}">
                <CommandBar.Content>
                    <!--Get MainPageTitle.Text from localized resources-->
                    <TextBlock x:Uid="MainPageTitle" />
                </CommandBar.Content>

                <!--All your AppBar buttons-->
                <!--Get SendAppBarButton.Label from localized resources-->
                <AppBarButton x:Uid="SendAppBarButton" Icon="Send" />

            </CommandBar>
        </DataTemplate>
    </behaviors:NavigationViewHeaderBehavior.HeaderTemplate>

    <Grid
        x:Name="ContentArea"
        Margin="{StaticResource MediumLeftRightMargin}">
        <Grid
            Background="{ThemeResource SystemControlPageBackgroundChromeLowBrush}">
            <!--The SystemControlPageBackgroundChromeLowBrush background represents where you should place your content.
                Place your content here.-->
        </Grid>
    </Grid>
</Page>

We are going to associate the HeaderContext to the ViewModel of the page in order to use the Command. We will do this from the code of the page.

public MainPage()
{
    InitializeComponent();
    SetBinding(NavigationViewHeaderBehavior.HeaderContextProperty, new Binding
    {
        Source = ViewModel,
        Mode = BindingMode.OneWay
    });
}

You can see an example of an advanced use of CommandBar and NavigationViewHeaderBehavior in the InkPages in WinTS.

When using MVVMBasic, MVVMLight, Caliburn or Prism, you can use x:Bind to bind properties to your ViewModel, associated to the HeaderContext.

When using CodeBehind, the HeaderContext is associated to the page's code behind file and x:Bind is not working correctly. More info on issue 2711

We're working on a solution with the NavView team, meanwhile you can use Binding and access the CodeBehind properties through the shellFrame's Content as the Datatemplate is executed in the Context of the NavigationView.

Text="{Binding Content.PropertyOnCodeBehind, ElementName=shellFrame, Mode=TwoWay}">

If you want to be able to add a command bar at ShellPage level, you can add it in the DefaultHeaderTemplate of the NavigationViewHeaderBehavior (ShellPage.xaml).

A Note about the above code examples.

Events and commands are not shown in the above code but can easily be added like any other button click event or command. Note that if using the techniques for adding the bar to every page, the events or commands should be handled by the ShellPageViewModel (or in ShellPage.xaml.cs if using CodeBehind.)

The examples also only show a single AppBarButton being added. This is to keep the code sample as simple as possible but you can add any appropriate content to the bar, as documented here.

Invoke code on NavigationView

Extending the app to add this functionality requires making two changes.

  1. Add a HyperLink in the FooterTemplate.
  2. Add a Command to handle code on HyperLink click.

ShellPage.xaml

<winui:NavigationView>
    <winui:NavigationView.PaneFooter>
        <StackPanel>
            <HyperlinkButton
                x:Uid="Shell_ShowInfo"
                Margin="16,0"
                Command="{x:Bind ViewModel.ShowInfoCommand}" />
        </StackPanel>
    </winui:NavigationView.PaneFooter>
</winui:NavigationView>

Add a command to run the code in ShellViewModel.cs (MVVMBasic or MVVMLight) or ShellPage.xaml.cs (CodeBehind)

    private ICommand _showInfoCommand;

    public ICommand ShowInfoCommand => _showInfoCommand ?? (_showInfoCommand = new RelayCommand(OnShowInfo));

    private void OnShowInfo()
    {
        // TODO: Run command code
    }

Change the text for Settings

The text label for the Settings page is supplied by the OS. This includes any translations, but it is possible to call this page something else.

Add a new resource with the name Shell_SettingsItem. (You can call it anything but it must match what's in the code below and it must not contain a period (.).)

In Shell.xaml.csmodify the constructor so it matches this (add the loaded event handler)

public ShellPage()
{
    InitializeComponent();
    DataContext = this;
    Initialize();

    navigationView.Loaded += (sender, e) =>
    {
        (navigationView.SettingsItem as WinUI.NavigationViewItem).Content = "Shell_SettingsItem".GetLocalized();
    };
}

The above will result in the text you specify being used in the app, like the one below.

Example of different Settings page label