/// <summary> /// Processes a <see cref="StackNavigatorRequest"/> based on its <see cref="StackNavigatorRequestType"/>. /// </summary> /// <param name="stackNavigator">The stack navigator.</param> /// <param name="ct">The cancellation token.</param> /// <param name="request">The request to process.</param> public static Task ProcessRequest(this IStackNavigator stackNavigator, CancellationToken ct, StackNavigatorRequest request) { switch (request.RequestType) { case StackNavigatorRequestType.NavigateForward: return(stackNavigator.Navigate(ct, request)); case StackNavigatorRequestType.NavigateBack: return(stackNavigator.NavigateBack(ct)); case StackNavigatorRequestType.Clear: return(stackNavigator.Clear(ct)); case StackNavigatorRequestType.RemoveEntry: return(stackNavigator.RemoveEntries(ct, request.EntryIndexesToRemove)); default: throw new NotSupportedException($"The request type '{request.RequestType}' is not supported."); } }
/// <summary> /// Tries to navigate back to the ViewModel matching <typeparamref name="TPageViewModel"/>. /// </summary> /// <remarks> /// If no previous entry matches <typeparamref name="TPageViewModel"/>, nothing happens. /// </remarks> /// <typeparam name="TPageViewModel">The ViewModel type.</typeparam> /// <param name="navigator">The stack navigator.</param> /// <param name="ct">The cancellation token.</param> /// <returns>True if the navigate back happened. False otherwise.</returns> public static async Task <bool> TryNavigateBackTo <TPageViewModel>(this IStackNavigator navigator, CancellationToken ct) { var logger = typeof(StackNavigatorExtensions).Log(); // Retrieve the current stack and its size var stack = navigator.State.Stack; var count = stack.Count; // Retrieve the instance of the target ViewModel var targetEntry = stack.FirstOrDefault(entry => entry.ViewModel.GetType() == typeof(TPageViewModel)); if (targetEntry != null) { // Retrieve the index of the target viewModel var startIndex = stack.ToList().IndexOf(targetEntry); // Count how many items we should delete between the target viewModel and the current page viewmodel var itemsToDelete = count - 1 - startIndex - 1; if (itemsToDelete > 0) { var indexesToRemove = Enumerable.Range(startIndex + 1, itemsToDelete); await navigator.RemoveEntries(ct, indexesToRemove); } // Navigate back to the target view model await navigator.NavigateBack(ct); return(true); } else { if (logger.IsEnabled(LogLevel.Warning)) { logger.LogWarning($"Can't navigate back to '{typeof(TPageViewModel).Name}' because it's not in the navigation stack."); } return(false); } }
/// <inheritdoc/> public Task <INavigableViewModel> NavigateBack(CancellationToken ct) { return(_inner.NavigateBack(ct)); }