Chinook.StackNavigation.Reactive 0.7.0

There is a newer version of this package available.
See the version list below for details.
dotnet add package Chinook.StackNavigation.Reactive --version 0.7.0                
NuGet\Install-Package Chinook.StackNavigation.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.StackNavigation.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.StackNavigation.Reactive --version 0.7.0                
#r "nuget: Chinook.StackNavigation.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.StackNavigation.Reactive as a Cake Addin
#addin nuget:?package=Chinook.StackNavigation.Reactive&version=0.7.0

// Install Chinook.StackNavigation.Reactive as a Cake Tool
#tool nuget:?package=Chinook.StackNavigation.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);

License

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);
}

Features

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.

Modals

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.

Changelog

Please consult the CHANGELOG for more information about version history.

License

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

Contributing

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

Be mindful of our Code of Conduct.

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

NuGet packages (1)

Showing the top 1 NuGet packages that depend on Chinook.StackNavigation.Reactive:

Package Downloads
Chinook.SectionsNavigation.Reactive

Unified cross-platform tools to perform ViewModel-based navigation.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
3.0.2 2,905 2/22/2024
3.0.1 8,916 1/18/2024
3.0.0 1,408 12/22/2023
3.0.0-feature.Uno5Update.7 152 12/6/2023
3.0.0-feature.Uno5Update.4 1,903 11/28/2023
2.1.2 6,950 2/22/2024
2.1.1 10,527 6/15/2023
2.1.0 441 6/15/2023
2.0.0 14,452 4/12/2023
1.1.2 60,228 10/14/2022
1.1.1 689 10/12/2022
1.1.0 2,553 9/23/2022
1.1.0-feature.dotnet6.12 151 9/22/2022
1.1.0-feature.dotnet6.4 134 9/16/2022
1.0.0 3,469 9/2/2022
0.7.0 735 8/30/2022
0.7.0-dev.91 14,695 5/17/2022
0.7.0-dev.88 14,000 4/13/2022
0.7.0-dev.86 178 4/12/2022
0.7.0-dev.83 299 3/30/2022
0.6.0-feature.uno-ui-4.79 177 3/15/2022
0.6.0-feature.uno-ui-4.78 160 3/15/2022
0.6.0-dev.80 317 3/15/2022
0.5.0-feature.uno-ui-4.77 7,731 1/25/2022
0.5.0-dev.73 10,943 1/24/2022
0.5.0-dev.71 156 1/20/2022
0.4.0-feature.uno-ui-4.70 210 12/20/2021
0.4.0-dev.69 10,025 10/12/2021
0.4.0-dev.67 34,869 5/26/2021
0.4.0-dev.65 265 4/20/2021
0.4.0-dev.62 1,683 4/19/2021
0.4.0-dev.59 8,977 4/6/2021
0.3.0-dev.53 228 3/30/2021
0.3.0-dev.50 7,997 3/16/2021
0.2.0-dev.46 1,605 12/17/2020
0.2.0-dev.44 5,403 12/4/2020
0.2.0-dev.42 293 12/4/2020
0.2.0-dev.39 323 11/2/2020
0.2.0-dev.37 9,341 8/21/2020
0.2.0-dev.33 5,348 8/13/2020
0.2.0-dev.31 335 6/26/2020
0.2.0-dev.29 314 6/26/2020