NavigationView
NavigationView is a top-level navigation control that provides a collapsible navigation pane (the "hamburger menu") and a content area. It is the primary way to implement top-level navigation in your app.
Tip
For a complete implementation example, see the WPF UI Gallery application.
Anatomy
The NavigationView control has several key areas:
- Pane: The area on the left or top that contains navigation items.
- Header: An area at the top of the content area, often used for a page title or a
BreadcrumbBar. - Content Area: The main area of the control where page content is displayed.
- AutoSuggestBox: An optional search box integrated into the navigation pane.
- MenuItems: The primary list of navigation items.
- FooterMenuItems: A secondary list of navigation items, typically for settings or about pages.
Basic Usage
Define NavigationView in your XAML and add NavigationViewItem objects to the MenuItems and FooterMenuItems collections.
<ui:NavigationView
xmlns:pages="clr-namespace:YourApp.Views.Pages"
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml">
<ui:NavigationView.MenuItems>
<ui:NavigationViewItem
Content="Home"
Icon="{ui:SymbolIcon Home24}"
TargetPageType="{x:Type pages:DashboardPage}" />
<ui:NavigationViewItem
Content="Data"
Icon="{ui:SymbolIcon DataHistogram24}"
TargetPageType="{x:Type pages:DataPage}" />
</ui:NavigationView.MenuItems>
<ui:NavigationView.FooterMenuItems>
<ui:NavigationViewItem
Content="Settings"
Icon="{ui:SymbolIcon Settings24}"
TargetPageType="{x:Type pages:SettingsPage}" />
</ui:NavigationView.FooterMenuItems>
</ui:NavigationView>
Note
TargetPageType is a required property on NavigationViewItem that specifies the page to navigate to when the item is selected. The value must be a System.Type.
Programmatic Navigation
You can navigate programmatically by calling the Navigate method with either the Type of the page or its PageTag.
// Navigate by Type
MyNavigationView.Navigate(typeof(SettingsPage));
// Navigate by Tag
MyNavigationView.Navigate("settings");
To use tags, you must define a PageTag on the NavigationViewItem. If not defined, a tag is automatically generated from the Content property (e.g., "Settings Page" becomes "settingspage").
<ui:NavigationViewItem
Content="Settings"
PageTag="settings"
TargetPageType="{x:Type pages:SettingsPage}" />
Back Navigation
NavigationView automatically handles back navigation. The back button is shown when CanGoBack is true. You can also call GoBack() programmatically.
if (MyNavigationView.CanGoBack)
{
MyNavigationView.GoBack();
}
Pane Display Mode
Control the visibility and behavior of the navigation pane with the PaneDisplayMode property.
Left: The pane is always open on the left.Top: The pane is shown as a horizontal bar at the top.LeftCompact: The pane is collapsed to show only icons, and expands on hover or when the hamburger button is clicked.LeftMinimal: The pane is hidden and can be opened as an overlay.
<ui:NavigationView PaneDisplayMode="Top" />
You can also control the pane's open state with the IsPaneOpen property.
Tip
To create a responsive layout that changes PaneDisplayMode based on window width, bind PaneDisplayMode to a property in your ViewModel and update it in the Window.SizeChanged event.
Header
The Header property provides a content area above the navigation frame. It is commonly used with a BreadcrumbBar to show the user's location.
<ui:NavigationView>
<ui:NavigationView.Header>
<ui:BreadcrumbBar />
</ui:NavigationView.Header>
</ui:NavigationView>
The BreadcrumbBar will automatically sync with the NavigationView's navigation history.
MVVM Integration
For MVVM applications, it is recommended to use INavigationService and IPageService for navigation and page resolution.
1. Service Configuration
First, register the required services and your pages/ViewModels with your dependency injection container.
// Using Microsoft.Extensions.DependencyInjection
Host.CreateDefaultBuilder()
.ConfigureServices((context, services) =>
{
// Main window
services.AddScoped<IWindow, MainWindow>();
services.AddScoped<MainWindowViewModel>();
// Services
services.AddSingleton<INavigationService, NavigationService>();
services.AddSingleton<IPageService, PageService>();
// Pages and ViewModels
services.AddScoped<DashboardPage>();
services.AddScoped<DashboardViewModel>();
services.AddScoped<SettingsPage>();
services.AddScoped<SettingsViewModel>();
}).Build();
2. ViewModel Setup
In your MainWindowViewModel, define collections for your navigation items and bind them to the NavigationView.
public partial class MainWindowViewModel : ObservableObject
{
[ObservableProperty]
private ICollection<object> _menuItems = new ObservableCollection<object>();
[ObservableProperty]
private ICollection<object> _footerMenuItems = new ObservableCollection<object>();
public MainWindowViewModel()
{
MenuItems = new ObservableCollection<object>
{
new NavigationViewItem("Home", SymbolRegular.Home24, typeof(DashboardPage)),
new NavigationViewItem("Data", SymbolRegular.DataHistogram24, typeof(DataPage))
};
FooterMenuItems = new ObservableCollection<object>
{
new NavigationViewItem("Settings", SymbolRegular.Settings24, typeof(SettingsPage))
};
}
}
3. View Setup
In your MainWindow.xaml, bind the MenuItemsSource and FooterMenuItemsSource properties to the collections in your ViewModel. Then, attach the INavigationService.
<ui:NavigationView
x:Name="RootNavigationView"
MenuItemsSource="{Binding MenuItems}"
FooterMenuItemsSource="{Binding FooterMenuItems}" />
public partial class MainWindow : IWindow
{
public MainWindow(
MainWindowViewModel viewModel,
INavigationService navigationService,
IPageService pageService
)
{
ViewModel = viewModel;
DataContext = this;
InitializeComponent();
// Attach the service to the NavigationView
navigationService.SetNavigationControl(RootNavigationView);
// You can also set the page service, which is required for some functionalities
RootNavigationView.SetPageService(pageService);
}
public MainWindowViewModel ViewModel { get; }
}
4. Navigating from a ViewModel
Inject INavigationService into any ViewModel and use it to navigate.
public partial class DashboardViewModel : ObservableObject
{
private readonly INavigationService _navigationService;
public DashboardViewModel(INavigationService navigationService)
{
_navigationService = navigationService;
}
[RelayCommand]
private void OnGoToSettings()
{
_navigationService.Navigate(typeof(SettingsPage));
}
}
Navigation Events
NavigationView provides several events to hook into the navigation lifecycle:
Navigating: Occurs before navigation starts. Can be cancelled.Navigated: Occurs after navigation is complete.SelectionChanged: Occurs when aNavigationViewItemis selected.
private void OnNavigating(NavigationView sender, NavigatingCancelEventArgs args)
{
// Don't navigate to settings if the user is not an admin
if (args.PageType == typeof(SettingsPage) && !_isAdmin)
{
args.Cancel = true;
}
}
Navigation-Aware Pages
Implement INavigationAware on your page's code-behind or INavigableView<T> on your ViewModel to receive navigation events directly.
INavigationAware
This interface is ideal for code-behind scenarios.
public partial class MyPage : INavigationAware
{
public void OnNavigatedTo()
{
// Page was navigated to
}
public void OnNavigatedFrom()
{
// Page was navigated away from
}
}
INavigableView<T>
This interface is designed for MVVM. Your page must inherit from INavigableView<T> where T is its ViewModel. The ViewModel will then receive the navigation calls.
Page:
[GalleryPage("My Page", SymbolRegular.Page24)]
public partial class MyPage : INavigableView<MyViewModel>
{
public MyViewModel ViewModel { get; }
public MyPage(MyViewModel viewModel)
{
ViewModel = viewModel;
DataContext = this;
InitializeComponent();
}
}
ViewModel:
public partial class MyViewModel : ObservableObject, INavigationAware
{
public void OnNavigatedTo()
{
// Page was navigated to
}
public void OnNavigatedFrom()
{
// Page was navigated away from
}
}
Important
For INavigableView<T> to work, your page must have a public ViewModel property that returns an instance of the ViewModel.
History and Caching
NavigationView maintains a navigation history.
History: A collection ofPageinstances that have been visited.CacheHistory: The number of pages to keep in memory. The default is0. Set to a value greater than 0 to cache pages. When a cached page is navigated to, its previous state is preserved.
<ui:NavigationView CacheHistory="5" />
Caution
Caching pages increases memory consumption. Use it only for pages that are expensive to create or where preserving state is critical. Avoid caching pages that display frequently changing data.