/// <summary> /// Sets the active section using the provided section name and navigates. /// </summary> /// <typeparam name="TViewModel">The type of the view model.</typeparam> /// <param name="sectionsNavigator">The sections navigator.</param> /// <param name="ct">The cancellation token.</param> /// <param name="sectionName">The name of the section to set as active.</param> /// <param name="viewModelProvider">The method to make the view model instance. It will be invoked only if necessary.</param> /// <param name="returnToRoot">When this is true, the navigator will navigate back to the view model matching the type <typeparamref name="TViewModel"/>.</param> /// <returns>The stack navigator of the active section.</returns> public static async Task <ISectionStackNavigator> SetActiveSection <TViewModel>(this ISectionsNavigator sectionsNavigator, CancellationToken ct, string sectionName, Func <TViewModel> viewModelProvider, bool returnToRoot = false) where TViewModel : INavigableViewModel { if (ct.IsCancellationRequested) { typeof(SectionsNavigatorExtensions).Log().LogWarning($"Canceled 'SetActiveSection' operation to '{typeof(TViewModel).Name}' because of cancellation token."); return(null); } // No cancellation beyond this point. ct = CancellationToken.None; var sectionNavigator = sectionsNavigator.State.Sections[sectionName]; if (sectionNavigator.State.Stack.LastOrDefault() == null) { // Create the default page if there's nothing in the section. await sectionNavigator.Navigate(ct, StackNavigatorRequest.GetNavigateRequest(viewModelProvider, suppressTransition: true)); } else if (returnToRoot && sectionNavigator.State.Stack.Last().ViewModel.GetType() != typeof(TViewModel)) { if (sectionNavigator.State.Stack.Any(e => e.ViewModel.GetType() == typeof(TViewModel))) { // If the stack contains the root page of the section, remove all other entries and navigate back to it. var indexesToRemove = sectionNavigator.State.Stack .Select((entry, index) => (entry, index)) .Where(t => t.entry.ViewModel.GetType() != typeof(TViewModel) && t.index < sectionNavigator.State.Stack.Count - 1) .Select(t => t.index) .ToList(); await sectionNavigator.RemoveEntries(ct, indexesToRemove); await sectionNavigator.NavigateBack(ct); } else { // If the section root page isn't in the stack, clear everything and navigate to it. await sectionNavigator.Navigate(ct, StackNavigatorRequest.GetNavigateRequest(viewModelProvider, suppressTransition: true, clearBackStack: true)); } } return(await sectionsNavigator.SetActiveSection(ct, SectionsNavigatorRequest.GetSetActiveSectionRequest(sectionName))); }
/// <summary> /// Sets the active section using the provided section name. /// </summary> /// <param name="sectionsNavigator">The sections navigator.</param> /// <param name="ct">The cancellation token.</param> /// <param name="sectionName">The name of the section to set as active.</param> /// <returns>The stack navigator of the active section.</returns> public static Task <ISectionStackNavigator> SetActiveSection(this ISectionsNavigator sectionsNavigator, CancellationToken ct, string sectionName) { return(sectionsNavigator.SetActiveSection(ct, SectionsNavigatorRequest.GetSetActiveSectionRequest(sectionName))); }