Chinook.SectionsNavigation.Reactive 0.7.0

.NET Standard 2.0
There is a newer version of this package available.
See the version list below for details.
dotnet add package Chinook.SectionsNavigation.Reactive --version 0.7.0
NuGet\Install-Package Chinook.SectionsNavigation.Reactive -Version 0.7.0
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Chinook.SectionsNavigation.Reactive" Version="0.7.0" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add Chinook.SectionsNavigation.Reactive --version 0.7.0
#r "nuget: Chinook.SectionsNavigation.Reactive, 0.7.0"
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install Chinook.SectionsNavigation.Reactive as a Cake Addin
#addin nuget:?package=Chinook.SectionsNavigation.Reactive&version=0.7.0

// Install Chinook.SectionsNavigation.Reactive as a Cake Tool
#tool nuget:?package=Chinook.SectionsNavigation.Reactive&version=0.7.0

Chinook StackNavigation and SectionsNavigation

This library provides unified cross-platform tools to perform ViewModel-based navigation using the Frame navigation model.

// Navigate to the PersonDetailsPage.
await navigator.Navigate(ct, () => new PersonDetailsPageViewModel());
// Navigate back.
await navigator.NavigateBack(ct);


Getting Started

1. Choose your Navigator

There are 2 types of navigators available:

  • IStackNavigator - Use this if your app would use a single Frame.

    Section Navigation

  • ISectionsNavigator - Use this if you want to use multiple frames (like sections tabs) or modals. Note that IStackNavigator is used as a building block by ISectionsNavigator.

    Section Navigation

2. Create your Navigator

See how to get you instance for StackNavigation or SectionsNavigation. Note that your code should always use the interface in order to be easily reused for integration tests.

3. Use your Navigator

There's a lot of things you can do. Here are some examples.

// Navigate to the PersonDetailsPage.
await navigator.Navigate(ct, () => new PersonDetailsPageViewModel());
// Navigate back.
await navigator.NavigateBack(ct);
// Navigate to the HomePage, clearing all other previous pages from the backstack.
await navigator.NavigateAndClear(ct, () => new HomePageViewModel());
Remove previous pages
// Navigate to Step 1
await navigator.Navigate(ct, () => new Step1PageViewModel());
// Navigate to Step 2
await navigator.Navigate(ct, () => new Step2PageViewModel());
// Navigate to Step 2.1
await navigator.Navigate(ct, () => new Step21PageViewModel());
// Navigate to Step 3
await navigator.Navigate(ct, () => new Step3PageViewModel());

// Remove the previous page (Step 2.1) from the backstack. 
await navigator.RemovePrevious(ct);
// Navigate back to Step 2
await navigator.NavigateBack(ct);

The following examples only apply to ISectionsNavigator.

Change between sections
// Go to Home section.
await sectionsNavigator.SetActiveSection(ct, "Home");
// Go to Messages section.
await sectionsNavigator.SetActiveSection(ct, "Messages");
// Go to Settings section.
await sectionsNavigator.SetActiveSection(ct, "Settings");
Return to root of section
// Go to Home section.
await sectionsNavigator.SetActiveSection(ct, "Home", () => new HomePageViewModel());
// Navigate forward to some details page in the Home section.
await sectionsNavigator.Navigate(ct, () => new PersonDetailsPageViewModel());
// Go to Messages section.
await sectionsNavigator.SetActiveSection(ct, "Messages");

// Return to Home section on the Home page, not the PersonDetails page.
await sectionsNavigator.SetActiveSection(ct, "Home", () => new HomePageViewModel(), returnToRoot: true);
Open and close modals
// Open LoginPage in a modal.
await sectionsNavigator.OpenModal(ct, () => new LoginPageViewModel());
// Close the modal.
await sectionsNavigator.CloseModal(ct);
Open modals behind other modals
// Open LoginPage in a modal with a priority of 2.
await sectionsNavigator.OpenModal(ct, () => new LoginPageViewModel(), priority = 2);

// Open the SurveyPage in a modal behind the LoginPage page modal, using a lower priority of 1.
// Because the SurveyPage opens with a lower priority, you don't actually see this change happen.
await sectionsNavigator.OpenModal(ct, () => new SurveyPageViewModel(), priority = 1);

// Close the top-most modal (LoginPage) to reveal the SurveyPage modal behind it.
await sectionsNavigator.CloseModal(ct);
Change sections behind modals
// Open LoginPage in a modal.
await sectionsNavigator.OpenModal(ct, () => new LoginPageViewModel());

// Change the section to Messages.
// Modals are displayed on top of sections, so you don't actually see this change happen.
await sectionsNavigator.SetActiveSection(ct, "Messages", () => new MessagesPageViewModel());

// Close the modal to reveal the Messages section.
await sectionsNavigator.CloseModal(ct);
// Go to Home section.
await sectionsNavigator.SetActiveSection(ct, "Home", () => new HomePageViewModel());
// Get the settings section navigator.
var settingsSection = sectionsNavigator.State.Sections["Settings"];

// Navigate forward to the SettingsPage, then the LicencePage in the Settings section.
// The Settings sections is not currently active, so you don't actually see this change happen.
await settingsSection.Navigate(ct, () => new SettingsPageViewModel());
await settingsSection.Navigate(ct, () => new LicencePageViewModel());

// Go to Settings section to see the Licence page.
await sectionsNavigator.SetActiveSection(ct, "Settings");
// Navigate back to SettingsPage.
await sectionsNavigator.NavigateBack(ct);
// Check whether the navigator can navigate back or close a modal.
// This us useful when dealing with an hardware back button.
if (sectionsNavigator.CanNavigateBackOrCloseModal())
  // Navigates back within the modal if the modal has multiple pages in its stack
  // Or closes the modal if there's a modal that has an empty backstack
  // Or navigates back in the active section.
  await sectionsNavigator.NavigateBackOrCloseModal(ct);


Ready for Dependency Injection

The two navigation services are made from simple interfaces. You can easily leverage containers such as Microsoft's Generic Host.

Ready for Integration Testing

Because this is ViewModel-based navigation and the navigator interfaces don't reference any UI type, you can use the navigators in Test Projects or Console Applications without changing your navigation logic. Just install the Chinook.SectionsNavigation or Chinook.StackNavigation packages and use the BlindSectionsNavigator or BlindStackNavigator implementations.

No Double Navigation

If you invoke 2 operations simultaneously (double tap, press 2 buttons with 2 fingers, etc.), only the first will actually run. This is because the request state (Processing, Processed or FailedToProcess) is part of the ISectionsNavigator.State. If a request is made while another is processing, the second request is cancelled.

Background Navigation

You can navigate in sections that are not active. This is useful if you want to prepare a section before entering it.

Transitions and Animations

For stack navigation, you can suppress the default transition using StackNavigatorRequest.SuppressTransitions.

For sections navigation, you can customize or disable animations using SectionsNavigatorRequest.TransitionInfo. You can read more on that here.


ISectionsNavigator allows you to handle multiple stacks of navigation in your app, including modals. This means you can easily handle navigation with your modals, since the modals are just in another navigation stack. For instance, the user can navigate back and forth in the modals, and your app can navigate the pages behind the modals, without breaking the flow.


Please consult the CHANGELOG for more information about version history.


This project is licensed under the Apache 2.0 license - see the LICENSE file for details.


Please read for details on the process for contributing to this project.

Be mindful of our Code of Conduct.

Product Versions
.NET net5.0 net5.0-windows net6.0 net6.0-android net6.0-ios net6.0-maccatalyst net6.0-macos net6.0-tvos net6.0-windows net7.0 net7.0-android net7.0-ios net7.0-maccatalyst net7.0-macos net7.0-tvos net7.0-windows
.NET Core netcoreapp2.0 netcoreapp2.1 netcoreapp2.2 netcoreapp3.0 netcoreapp3.1
.NET Standard netstandard2.0 netstandard2.1
.NET Framework net461 net462 net463 net47 net471 net472 net48 net481
MonoAndroid monoandroid
MonoMac monomac
MonoTouch monotouch
Tizen tizen40 tizen60
Xamarin.iOS xamarinios
Xamarin.Mac xamarinmac
Xamarin.TVOS xamarintvos
Xamarin.WatchOS xamarinwatchos
Compatible target framework(s)
Additional computed target framework(s)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
1.1.2 10,961 10/14/2022
1.1.1 263 10/12/2022
1.1.0 1,872 9/23/2022
1.1.0-feature.dotnet6.12 70 9/22/2022
1.1.0-feature.dotnet6.4 72 9/16/2022
1.0.0 1,139 9/2/2022
0.7.0 283 8/30/2022
0.7.0-dev.91 14,253 5/17/2022
0.7.0-dev.88 13,031 4/13/2022
0.7.0-dev.86 115 4/12/2022
0.7.0-dev.83 228 3/30/2022 118 3/15/2022 97 3/15/2022
0.6.0-dev.80 257 3/15/2022 5,295 1/25/2022
0.5.0-dev.73 10,211 1/24/2022
0.5.0-dev.71 118 1/20/2022 165 12/20/2021
0.4.0-dev.69 9,940 10/12/2021
0.4.0-dev.67 34,166 5/26/2021
0.4.0-dev.65 217 4/20/2021
0.4.0-dev.62 1,637 4/19/2021
0.4.0-dev.59 8,910 4/6/2021
0.3.0-dev.53 167 3/30/2021
0.3.0-dev.50 7,886 3/16/2021
0.2.0-dev.46 1,552 12/17/2020
0.2.0-dev.44 5,356 12/4/2020
0.2.0-dev.42 241 12/4/2020
0.2.0-dev.39 268 11/2/2020
0.2.0-dev.37 9,303 8/21/2020
0.2.0-dev.33 5,320 8/13/2020
0.2.0-dev.31 270 6/26/2020
0.2.0-dev.29 243 6/26/2020