From 6ee0fa46994b2fddc86dbd8e030ba740efa81262 Mon Sep 17 00:00:00 2001 From: niimima Date: Fri, 5 Jul 2024 16:12:14 +0900 Subject: [PATCH 1/8] [WIP] Add NavigateFromAsync methods and unittests. --- .../Navigation/INavigationService.cs | 9 +++ .../INavigationServiceExtensions.cs | 9 +++ .../Navigation/PageNavigationService.cs | 41 ++++++++++++++ .../Fixtures/Navigation/NavigationTests.cs | 56 +++++++++++++++++++ 4 files changed, 115 insertions(+) diff --git a/src/Maui/Prism.Maui/Navigation/INavigationService.cs b/src/Maui/Prism.Maui/Navigation/INavigationService.cs index 25e1e12f0..7c20e563d 100644 --- a/src/Maui/Prism.Maui/Navigation/INavigationService.cs +++ b/src/Maui/Prism.Maui/Navigation/INavigationService.cs @@ -40,6 +40,15 @@ public interface INavigationService /// Task NavigateAsync(Uri uri, INavigationParameters parameters); + /// + /// Initiates navigation from the using the specified . + /// + /// The name of the View to navigate from + /// The route Uri to navigate from that view + /// The navigation parameters + /// If true a navigate from operation was successful. If false the navigate from operation failed. + Task NavigateFromAsync(string viewName, Uri route, INavigationParameters parameters); + /// /// Selects a Tab of the TabbedPage parent and Navigates to a specified Uri /// diff --git a/src/Maui/Prism.Maui/Navigation/INavigationServiceExtensions.cs b/src/Maui/Prism.Maui/Navigation/INavigationServiceExtensions.cs index 7e1097aef..4d24fc3f3 100644 --- a/src/Maui/Prism.Maui/Navigation/INavigationServiceExtensions.cs +++ b/src/Maui/Prism.Maui/Navigation/INavigationServiceExtensions.cs @@ -106,6 +106,15 @@ public static Task NavigateAsync(this INavigationService navi return navigationService.NavigateAsync(name, GetNavigationParameters(parameters)); } + /// + /// Initiates navigation to the target specified by the from the . + /// + /// The name of the View to navigate to + /// The route Uri to navigate to + /// If true a navigate from operation was successful. If false the navigate from operation failed. + public static Task NavigateFromAsync(this INavigationService navigationService, string viewName, Uri route) => + navigationService.NavigateFromAsync(viewName, route, new NavigationParameters()); + /// /// Provides an easy to use way to provide an Error Callback without using await NavigationService /// diff --git a/src/Maui/Prism.Maui/Navigation/PageNavigationService.cs b/src/Maui/Prism.Maui/Navigation/PageNavigationService.cs index 7af73d30a..0df6bfef6 100644 --- a/src/Maui/Prism.Maui/Navigation/PageNavigationService.cs +++ b/src/Maui/Prism.Maui/Navigation/PageNavigationService.cs @@ -333,6 +333,47 @@ public virtual async Task NavigateAsync(Uri uri, INavigationP } } + /// + public virtual async Task NavigateFromAsync(string viewName, Uri route, INavigationParameters parameters) + { + await WaitForPendingNavigationRequests(); + + try + { + parameters ??= new NavigationParameters(); + + NavigationSource = PageNavigationSource.NavigationService; + + var routeSegments = UriParsingHelper.GetUriSegments(route); + + var page = GetPageFromWindow(); + if (page is not null && ViewModelLocator.GetNavigationName(page) == viewName) + { + await ProcessNavigation(page, routeSegments, parameters, null, null); + } + else + { + var viewNameSegment = new Queue(); + viewNameSegment.Enqueue(viewName); + var navigationSegments = new Queue(viewNameSegment.Concat(routeSegments)); + + await ProcessNavigationForAbsoluteUri(navigationSegments, parameters, null, null); + } + + return Notify(route, parameters); + } + catch (Exception ex) + { + return Notify(route, parameters, ex); + } + finally + { + _lastNavigate = DateTime.Now; + NavigationSource = PageNavigationSource.Device; + _semaphore.Release(); + } + } + /// /// Selects a Tab of the TabbedPage parent. /// diff --git a/tests/Maui/Prism.DryIoc.Maui.Tests/Fixtures/Navigation/NavigationTests.cs b/tests/Maui/Prism.DryIoc.Maui.Tests/Fixtures/Navigation/NavigationTests.cs index fca62828a..ccc169f16 100644 --- a/tests/Maui/Prism.DryIoc.Maui.Tests/Fixtures/Navigation/NavigationTests.cs +++ b/tests/Maui/Prism.DryIoc.Maui.Tests/Fixtures/Navigation/NavigationTests.cs @@ -509,6 +509,62 @@ public async Task Navigation_Animation_IsFalse() Assert.False(push.Animated); } + [Fact] + public async Task Navigation_FromPageUsingRoot() + { + var mauiApp = CreateBuilder(prism => prism.CreateWindow("MockHome/NavigationPage/MockViewA")) + .Build(); + var window = GetWindow(mauiApp); + + Assert.IsAssignableFrom(window.Page); + var rootPage = (MockHome)window.Page; + Assert.NotNull(rootPage); + + Assert.NotNull(rootPage.Detail); + Assert.IsAssignableFrom(rootPage.Detail); + var navigatingPage = (NavigationPage)rootPage.Detail; + Assert.NotNull(navigatingPage); + Assert.IsType(navigatingPage.CurrentPage); + + var result = await navigatingPage.CurrentPage.GetContainerProvider() + .Resolve() + .NavigateFromAsync("MockHome", UriParsingHelper.Parse("NavigationPage/MockViewB"), null); + + Assert.True(result.Success); + + Assert.NotNull(rootPage.Detail); + var navigatedPage = (NavigationPage)rootPage.Detail; + Assert.IsType(navigatedPage.CurrentPage); + } + + [Fact] + public async Task Navigation_FromNotRootPageUsingRoot() + { + var mauiApp = CreateBuilder(prism => prism.CreateWindow("MockHome/NavigationPage/MockViewA")) + .Build(); + var window = GetWindow(mauiApp); + + Assert.IsAssignableFrom(window.Page); + var rootPage = (MockHome)window.Page; + Assert.NotNull(rootPage); + + Assert.NotNull(rootPage.Detail); + Assert.IsAssignableFrom(rootPage.Detail); + var navigatingPage = (NavigationPage)rootPage.Detail; + Assert.NotNull(navigatingPage); + Assert.IsType(navigatingPage.CurrentPage); + + var result = await navigatingPage.CurrentPage.GetContainerProvider() + .Resolve() + .NavigateFromAsync("NavigationPage", UriParsingHelper.Parse("MockViewB"), null); + + Assert.True(result.Success); + + Assert.NotNull(rootPage.Detail); + var navigatedPage = (NavigationPage)rootPage.Detail; + Assert.IsType(navigatedPage.CurrentPage); + } + [Theory] [InlineData("MockViewA", "MockViewB", null)] [InlineData("NavigationPage/MockViewA", "MockViewB?useModalNavigation=true", true)] From 86b68a5fa73f953e81db6c8eebc8dd567f9bb883 Mon Sep 17 00:00:00 2001 From: niimima Date: Fri, 5 Jul 2024 16:48:47 +0900 Subject: [PATCH 2/8] Modify NavigateFromAsync method and unittests. --- .../Navigation/PageNavigationService.cs | 17 +++---- .../Fixtures/Navigation/NavigationTests.cs | 51 +++++++++---------- 2 files changed, 30 insertions(+), 38 deletions(-) diff --git a/src/Maui/Prism.Maui/Navigation/PageNavigationService.cs b/src/Maui/Prism.Maui/Navigation/PageNavigationService.cs index 0df6bfef6..471fd41c4 100644 --- a/src/Maui/Prism.Maui/Navigation/PageNavigationService.cs +++ b/src/Maui/Prism.Maui/Navigation/PageNavigationService.cs @@ -346,19 +346,16 @@ public virtual async Task NavigateFromAsync(string viewName, var routeSegments = UriParsingHelper.GetUriSegments(route); - var page = GetPageFromWindow(); - if (page is not null && ViewModelLocator.GetNavigationName(page) == viewName) + // Find a page that matches the viewName. + var page = GetCurrentPage(); + while (page != null) { - await ProcessNavigation(page, routeSegments, parameters, null, null); + if (page is not null && ViewModelLocator.GetNavigationName(page) == viewName) + break; + page = page.GetParentPage(); } - else - { - var viewNameSegment = new Queue(); - viewNameSegment.Enqueue(viewName); - var navigationSegments = new Queue(viewNameSegment.Concat(routeSegments)); - await ProcessNavigationForAbsoluteUri(navigationSegments, parameters, null, null); - } + await ProcessNavigation(page, routeSegments, parameters, null, null); return Notify(route, parameters); } diff --git a/tests/Maui/Prism.DryIoc.Maui.Tests/Fixtures/Navigation/NavigationTests.cs b/tests/Maui/Prism.DryIoc.Maui.Tests/Fixtures/Navigation/NavigationTests.cs index ccc169f16..70db25cd6 100644 --- a/tests/Maui/Prism.DryIoc.Maui.Tests/Fixtures/Navigation/NavigationTests.cs +++ b/tests/Maui/Prism.DryIoc.Maui.Tests/Fixtures/Navigation/NavigationTests.cs @@ -510,59 +510,54 @@ public async Task Navigation_Animation_IsFalse() } [Fact] - public async Task Navigation_FromPageUsingRoot() + public async Task Navigation_FromPageUsingRoute() { var mauiApp = CreateBuilder(prism => prism.CreateWindow("MockHome/NavigationPage/MockViewA")) .Build(); var window = GetWindow(mauiApp); - Assert.IsAssignableFrom(window.Page); - var rootPage = (MockHome)window.Page; - Assert.NotNull(rootPage); - - Assert.NotNull(rootPage.Detail); - Assert.IsAssignableFrom(rootPage.Detail); - var navigatingPage = (NavigationPage)rootPage.Detail; - Assert.NotNull(navigatingPage); - Assert.IsType(navigatingPage.CurrentPage); + var pageNavigatingFrom = (MockHome)window.Page; + var navigationPage = (NavigationPage)pageNavigatingFrom.Detail; + Assert.IsType(navigationPage.CurrentPage); - var result = await navigatingPage.CurrentPage.GetContainerProvider() + var result = await navigationPage.CurrentPage.GetContainerProvider() .Resolve() .NavigateFromAsync("MockHome", UriParsingHelper.Parse("NavigationPage/MockViewB"), null); Assert.True(result.Success); - Assert.NotNull(rootPage.Detail); - var navigatedPage = (NavigationPage)rootPage.Detail; - Assert.IsType(navigatedPage.CurrentPage); + // MockHome(FlyoutPage) has not been replaced. + var pageNavigatedFrom = (MockHome)window.Page; + Assert.Equal(pageNavigatingFrom, pageNavigatedFrom); + + // Navigation should be succeeded. + navigationPage = (NavigationPage)pageNavigatedFrom.Detail; + Assert.IsType(navigationPage.CurrentPage); } [Fact] - public async Task Navigation_FromNotRootPageUsingRoot() + public async Task Navigation_FromIntermediatePageUsingRoute() { var mauiApp = CreateBuilder(prism => prism.CreateWindow("MockHome/NavigationPage/MockViewA")) .Build(); var window = GetWindow(mauiApp); - Assert.IsAssignableFrom(window.Page); - var rootPage = (MockHome)window.Page; - Assert.NotNull(rootPage); - - Assert.NotNull(rootPage.Detail); - Assert.IsAssignableFrom(rootPage.Detail); - var navigatingPage = (NavigationPage)rootPage.Detail; - Assert.NotNull(navigatingPage); - Assert.IsType(navigatingPage.CurrentPage); + var mockHome = (MockHome)window.Page; + var pageNavigatingFrom = (NavigationPage)mockHome.Detail; + Assert.IsType(pageNavigatingFrom.CurrentPage); - var result = await navigatingPage.CurrentPage.GetContainerProvider() + var result = await pageNavigatingFrom.CurrentPage.GetContainerProvider() .Resolve() .NavigateFromAsync("NavigationPage", UriParsingHelper.Parse("MockViewB"), null); Assert.True(result.Success); - Assert.NotNull(rootPage.Detail); - var navigatedPage = (NavigationPage)rootPage.Detail; - Assert.IsType(navigatedPage.CurrentPage); + // NavigationPage has not been replaced. + var pageNavigatedFrom = (NavigationPage)mockHome.Detail; + Assert.Equal(pageNavigatingFrom, pageNavigatedFrom); + + // Navigation should be succeeded. + Assert.IsType(pageNavigatedFrom.CurrentPage); } [Theory] From 41b32709b967c507ff65f53d3dd4a98cfd1d7b5b Mon Sep 17 00:00:00 2001 From: niimima Date: Mon, 29 Jul 2024 11:21:43 +0900 Subject: [PATCH 3/8] Modifies NavigateFromAsync to use navigationStack --- .../Navigation/PageNavigationService.cs | 38 +++++++++++++++---- .../Navigation/NavigationException.cs | 5 +++ .../Fixtures/Navigation/NavigationTests.cs | 25 ++++-------- 3 files changed, 44 insertions(+), 24 deletions(-) diff --git a/src/Maui/Prism.Maui/Navigation/PageNavigationService.cs b/src/Maui/Prism.Maui/Navigation/PageNavigationService.cs index 471fd41c4..da138875f 100644 --- a/src/Maui/Prism.Maui/Navigation/PageNavigationService.cs +++ b/src/Maui/Prism.Maui/Navigation/PageNavigationService.cs @@ -340,22 +340,29 @@ public virtual async Task NavigateFromAsync(string viewName, try { + if (route.IsAbsoluteUri) throw new NavigationException(NavigationException.UnsupportedAbsoluteUri); + parameters ??= new NavigationParameters(); NavigationSource = PageNavigationSource.NavigationService; - var routeSegments = UriParsingHelper.GetUriSegments(route); + var navigationSegments = UriParsingHelper.GetUriSegments(route); // Find a page that matches the viewName. - var page = GetCurrentPage(); - while (page != null) + var currentPage = GetCurrentPage(); + var navigationPages = currentPage.Navigation.NavigationStack.ToList(); + navigationPages.Reverse(); + var foundPage = navigationPages.FirstOrDefault(page => ViewModelLocator.GetNavigationName(page) == viewName); + var removePageCount = navigationPages.IndexOf(foundPage); + + // Insert RemovePageSegment. + var routeString = route.ToString(); + for (int i = 0; i < removePageCount; i++) { - if (page is not null && ViewModelLocator.GetNavigationName(page) == viewName) - break; - page = page.GetParentPage(); + AddToFront(navigationSegments, RemovePageSegment); } - await ProcessNavigation(page, routeSegments, parameters, null, null); + await ProcessNavigation(currentPage, navigationSegments, parameters, null, null); return Notify(route, parameters); } @@ -371,6 +378,23 @@ public virtual async Task NavigateFromAsync(string viewName, } } + private static void AddToFront(Queue queue, T element) + { + var tempQueue = new Queue(); + + while (queue.Count > 0) + { + tempQueue.Enqueue(queue.Dequeue()); + } + + queue.Enqueue(element); + + while (tempQueue.Count > 0) + { + queue.Enqueue(tempQueue.Dequeue()); + } + } + /// /// Selects a Tab of the TabbedPage parent. /// diff --git a/src/Prism.Core/Navigation/NavigationException.cs b/src/Prism.Core/Navigation/NavigationException.cs index 1ffecac4b..1077f64d0 100644 --- a/src/Prism.Core/Navigation/NavigationException.cs +++ b/src/Prism.Core/Navigation/NavigationException.cs @@ -72,6 +72,11 @@ public class NavigationException : Exception /// public const string UnknownException = "An unknown error occurred. You may need to specify whether to Use Modal Navigation or not."; + /// + /// The Message returned when an absolute path is specified but not supported. + /// + public const string UnsupportedAbsoluteUri = "An unsupported absolute uri. Please use a relative URI."; + /// /// Initializes a new instance of the /// diff --git a/tests/Maui/Prism.DryIoc.Maui.Tests/Fixtures/Navigation/NavigationTests.cs b/tests/Maui/Prism.DryIoc.Maui.Tests/Fixtures/Navigation/NavigationTests.cs index 70db25cd6..ba5ed8903 100644 --- a/tests/Maui/Prism.DryIoc.Maui.Tests/Fixtures/Navigation/NavigationTests.cs +++ b/tests/Maui/Prism.DryIoc.Maui.Tests/Fixtures/Navigation/NavigationTests.cs @@ -510,29 +510,20 @@ public async Task Navigation_Animation_IsFalse() } [Fact] - public async Task Navigation_FromPageUsingRoute() + public async Task Navigation_FromPageUsingRoute_OnNavigationPage() { - var mauiApp = CreateBuilder(prism => prism.CreateWindow("MockHome/NavigationPage/MockViewA")) + var mauiApp = CreateBuilder(prism => prism.CreateWindow("NavigationPage/MockViewA/MockViewB/MockViewC")) .Build(); var window = GetWindow(mauiApp); + var navigationService = Prism.Navigation.Xaml.Navigation.GetNavigationService(window.CurrentPage); + var currentNavigationStackUri = string.Join("/", window.CurrentPage.Navigation.NavigationStack.Select(v => v.GetType().Name)); + Assert.Equal("MockViewA/MockViewB/MockViewC", currentNavigationStackUri); - var pageNavigatingFrom = (MockHome)window.Page; - var navigationPage = (NavigationPage)pageNavigatingFrom.Detail; - Assert.IsType(navigationPage.CurrentPage); - - var result = await navigationPage.CurrentPage.GetContainerProvider() - .Resolve() - .NavigateFromAsync("MockHome", UriParsingHelper.Parse("NavigationPage/MockViewB"), null); + var result = await navigationService.NavigateFromAsync("MockViewA", UriParsingHelper.Parse("MockViewD/MockViewE"), null); Assert.True(result.Success); - - // MockHome(FlyoutPage) has not been replaced. - var pageNavigatedFrom = (MockHome)window.Page; - Assert.Equal(pageNavigatingFrom, pageNavigatedFrom); - - // Navigation should be succeeded. - navigationPage = (NavigationPage)pageNavigatedFrom.Detail; - Assert.IsType(navigationPage.CurrentPage); + currentNavigationStackUri = string.Join("/", window.CurrentPage.Navigation.NavigationStack.Select(v => v.GetType().Name)); + Assert.Equal("MockViewA/MockViewD/MockViewE", currentNavigationStackUri); } [Fact] From e1a4cf5c68b05ec5552260652bbd2c7a40d69cc2 Mon Sep 17 00:00:00 2001 From: niimima Date: Mon, 29 Jul 2024 13:59:27 +0900 Subject: [PATCH 4/8] Modify NavigateFromAsync to find parent pages --- .../Navigation/PageNavigationService.cs | 26 ++++++++++++++----- .../Fixtures/Navigation/NavigationTests.cs | 19 +++++++++++++- 2 files changed, 38 insertions(+), 7 deletions(-) diff --git a/src/Maui/Prism.Maui/Navigation/PageNavigationService.cs b/src/Maui/Prism.Maui/Navigation/PageNavigationService.cs index da138875f..e4b3e5852 100644 --- a/src/Maui/Prism.Maui/Navigation/PageNavigationService.cs +++ b/src/Maui/Prism.Maui/Navigation/PageNavigationService.cs @@ -353,13 +353,27 @@ public virtual async Task NavigateFromAsync(string viewName, var navigationPages = currentPage.Navigation.NavigationStack.ToList(); navigationPages.Reverse(); var foundPage = navigationPages.FirstOrDefault(page => ViewModelLocator.GetNavigationName(page) == viewName); - var removePageCount = navigationPages.IndexOf(foundPage); - - // Insert RemovePageSegment. - var routeString = route.ToString(); - for (int i = 0; i < removePageCount; i++) + if (foundPage is null) { - AddToFront(navigationSegments, RemovePageSegment); + var page = currentPage; + while (page != null) + { + if (page is not null && ViewModelLocator.GetNavigationName(page) == viewName) + break; + page = page.GetParentPage(); + } + currentPage = page; + } + else + { + var removePageCount = navigationPages.IndexOf(foundPage); + + // Insert RemovePageSegment. + var routeString = route.ToString(); + for (int i = 0; i < removePageCount; i++) + { + AddToFront(navigationSegments, RemovePageSegment); + } } await ProcessNavigation(currentPage, navigationSegments, parameters, null, null); diff --git a/tests/Maui/Prism.DryIoc.Maui.Tests/Fixtures/Navigation/NavigationTests.cs b/tests/Maui/Prism.DryIoc.Maui.Tests/Fixtures/Navigation/NavigationTests.cs index ba5ed8903..2d2a65156 100644 --- a/tests/Maui/Prism.DryIoc.Maui.Tests/Fixtures/Navigation/NavigationTests.cs +++ b/tests/Maui/Prism.DryIoc.Maui.Tests/Fixtures/Navigation/NavigationTests.cs @@ -510,7 +510,7 @@ public async Task Navigation_Animation_IsFalse() } [Fact] - public async Task Navigation_FromPageUsingRoute_OnNavigationPage() + public async Task Navigation_FromPageUsingRoute() { var mauiApp = CreateBuilder(prism => prism.CreateWindow("NavigationPage/MockViewA/MockViewB/MockViewC")) .Build(); @@ -526,6 +526,23 @@ public async Task Navigation_FromPageUsingRoute_OnNavigationPage() Assert.Equal("MockViewA/MockViewD/MockViewE", currentNavigationStackUri); } + [Fact] + public async Task Navigation_FromRootNavigationPageUsingRoute() + { + var mauiApp = CreateBuilder(prism => prism.CreateWindow("NavigationPage/MockViewA/MockViewB/MockViewC")) + .Build(); + var window = GetWindow(mauiApp); + var navigationService = Prism.Navigation.Xaml.Navigation.GetNavigationService(window.CurrentPage); + var currentNavigationStackUri = string.Join("/", window.CurrentPage.Navigation.NavigationStack.Select(v => v.GetType().Name)); + Assert.Equal("MockViewA/MockViewB/MockViewC", currentNavigationStackUri); + + var result = await navigationService.NavigateFromAsync("NavigationPage", UriParsingHelper.Parse("MockViewD/MockViewE"), null); + + Assert.True(result.Success); + currentNavigationStackUri = string.Join("/", window.CurrentPage.Navigation.NavigationStack.Select(v => v.GetType().Name)); + Assert.Equal("MockViewD/MockViewE", currentNavigationStackUri); + } + [Fact] public async Task Navigation_FromIntermediatePageUsingRoute() { From b1dcfc2d807158fd45e6436f4c8d70f0027bed33 Mon Sep 17 00:00:00 2001 From: niimima Date: Mon, 29 Jul 2024 14:10:34 +0900 Subject: [PATCH 5/8] Modify UnitTest --- .../Fixtures/Navigation/NavigationTests.cs | 21 +++++++------------ 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/tests/Maui/Prism.DryIoc.Maui.Tests/Fixtures/Navigation/NavigationTests.cs b/tests/Maui/Prism.DryIoc.Maui.Tests/Fixtures/Navigation/NavigationTests.cs index 2d2a65156..33b8f3c0f 100644 --- a/tests/Maui/Prism.DryIoc.Maui.Tests/Fixtures/Navigation/NavigationTests.cs +++ b/tests/Maui/Prism.DryIoc.Maui.Tests/Fixtures/Navigation/NavigationTests.cs @@ -544,28 +544,21 @@ public async Task Navigation_FromRootNavigationPageUsingRoute() } [Fact] - public async Task Navigation_FromIntermediatePageUsingRoute() + public async Task Navigation_FromFlyoutPageUsingRoute() { var mauiApp = CreateBuilder(prism => prism.CreateWindow("MockHome/NavigationPage/MockViewA")) .Build(); var window = GetWindow(mauiApp); - var mockHome = (MockHome)window.Page; - var pageNavigatingFrom = (NavigationPage)mockHome.Detail; - Assert.IsType(pageNavigatingFrom.CurrentPage); + var mockHome = (FlyoutPage)window.Page; + var navigationPage = (NavigationPage)mockHome.Detail; + Assert.IsType(navigationPage.CurrentPage); - var result = await pageNavigatingFrom.CurrentPage.GetContainerProvider() - .Resolve() - .NavigateFromAsync("NavigationPage", UriParsingHelper.Parse("MockViewB"), null); + var navigationService = Prism.Navigation.Xaml.Navigation.GetNavigationService(window.CurrentPage); + var result = await navigationService.NavigateFromAsync("MockHome", UriParsingHelper.Parse("MockViewB"), null); Assert.True(result.Success); - - // NavigationPage has not been replaced. - var pageNavigatedFrom = (NavigationPage)mockHome.Detail; - Assert.Equal(pageNavigatingFrom, pageNavigatedFrom); - - // Navigation should be succeeded. - Assert.IsType(pageNavigatedFrom.CurrentPage); + Assert.IsType(mockHome.Detail); } [Theory] From 5af4754cb667df8a3f5d699939fb2bc64a86fa3d Mon Sep 17 00:00:00 2001 From: niimima Date: Mon, 29 Jul 2024 15:35:31 +0900 Subject: [PATCH 6/8] Modify GetParentPage access modifier --- src/Maui/Prism.Maui/Extensions/VisualElementExtensions.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Maui/Prism.Maui/Extensions/VisualElementExtensions.cs b/src/Maui/Prism.Maui/Extensions/VisualElementExtensions.cs index 599049579..fb14bfa7e 100644 --- a/src/Maui/Prism.Maui/Extensions/VisualElementExtensions.cs +++ b/src/Maui/Prism.Maui/Extensions/VisualElementExtensions.cs @@ -1,4 +1,4 @@ -namespace Prism.Extensions; +namespace Prism.Extensions; internal static class VisualElementExtensions { @@ -17,7 +17,7 @@ public static Element GetRoot(this Element element) }; } - internal static Page GetParentPage(this Element visualElement) + public static Page GetParentPage(this Element visualElement) { return visualElement.Parent switch { From a33db2f73074296a7a47d2a4359b5ce12121c071 Mon Sep 17 00:00:00 2001 From: niimima Date: Mon, 29 Jul 2024 16:50:15 +0900 Subject: [PATCH 7/8] Revert "Modify GetParentPage access modifier" This reverts commit 5af4754cb667df8a3f5d699939fb2bc64a86fa3d. --- src/Maui/Prism.Maui/Extensions/VisualElementExtensions.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Maui/Prism.Maui/Extensions/VisualElementExtensions.cs b/src/Maui/Prism.Maui/Extensions/VisualElementExtensions.cs index fb14bfa7e..599049579 100644 --- a/src/Maui/Prism.Maui/Extensions/VisualElementExtensions.cs +++ b/src/Maui/Prism.Maui/Extensions/VisualElementExtensions.cs @@ -1,4 +1,4 @@ -namespace Prism.Extensions; +namespace Prism.Extensions; internal static class VisualElementExtensions { @@ -17,7 +17,7 @@ public static Element GetRoot(this Element element) }; } - public static Page GetParentPage(this Element visualElement) + internal static Page GetParentPage(this Element visualElement) { return visualElement.Parent switch { From 7f8a12fad2a1ad75ecb1a78041f58bf204311afb Mon Sep 17 00:00:00 2001 From: niimima Date: Mon, 29 Jul 2024 16:58:12 +0900 Subject: [PATCH 8/8] Refactor insert RemovePageSegment --- .../Navigation/PageNavigationService.cs | 29 ++++++------------- 1 file changed, 9 insertions(+), 20 deletions(-) diff --git a/src/Maui/Prism.Maui/Navigation/PageNavigationService.cs b/src/Maui/Prism.Maui/Navigation/PageNavigationService.cs index e4b3e5852..f0e82dd8d 100644 --- a/src/Maui/Prism.Maui/Navigation/PageNavigationService.cs +++ b/src/Maui/Prism.Maui/Navigation/PageNavigationService.cs @@ -355,6 +355,7 @@ public virtual async Task NavigateFromAsync(string viewName, var foundPage = navigationPages.FirstOrDefault(page => ViewModelLocator.GetNavigationName(page) == viewName); if (foundPage is null) { + // Find a page from parents. var page = currentPage; while (page != null) { @@ -366,14 +367,19 @@ public virtual async Task NavigateFromAsync(string viewName, } else { + // Insert RemovePageSegment. var removePageCount = navigationPages.IndexOf(foundPage); - // Insert RemovePageSegment. - var routeString = route.ToString(); + var tempQueue = new Queue(); for (int i = 0; i < removePageCount; i++) { - AddToFront(navigationSegments, RemovePageSegment); + tempQueue.Enqueue(RemovePageSegment); + } + while(navigationSegments.Count > 0) + { + tempQueue.Enqueue(navigationSegments.Dequeue()); } + navigationSegments = tempQueue; } await ProcessNavigation(currentPage, navigationSegments, parameters, null, null); @@ -392,23 +398,6 @@ public virtual async Task NavigateFromAsync(string viewName, } } - private static void AddToFront(Queue queue, T element) - { - var tempQueue = new Queue(); - - while (queue.Count > 0) - { - tempQueue.Enqueue(queue.Dequeue()); - } - - queue.Enqueue(element); - - while (tempQueue.Count > 0) - { - queue.Enqueue(tempQueue.Dequeue()); - } - } - /// /// Selects a Tab of the TabbedPage parent. ///