From b2bf48eb32b845d45923e7aad3d3e3d3bb2cfa3b Mon Sep 17 00:00:00 2001 From: Dan Siegel Date: Thu, 25 May 2023 07:29:04 -0600 Subject: [PATCH 1/2] fix: android back button --- e2e/Maui/PrismMauiDemo.sln | 3 +- src/Maui/Prism.Maui/Common/MvvmHelpers.cs | 33 ++++++++++- .../Controls/PrismNavigationPage.cs | 5 +- src/Maui/Prism.Maui/Navigation/PrismWindow.cs | 58 ++++++++++++++++++- src/Maui/Prism.Maui/PrismAppBuilder.cs | 21 +++---- 5 files changed, 102 insertions(+), 18 deletions(-) diff --git a/e2e/Maui/PrismMauiDemo.sln b/e2e/Maui/PrismMauiDemo.sln index 44bc5dff8c..4e651af936 100644 --- a/e2e/Maui/PrismMauiDemo.sln +++ b/e2e/Maui/PrismMauiDemo.sln @@ -29,7 +29,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Prism.Maui.Tests", "..\..\t EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Prism.Core.Tests", "..\..\tests\Prism.Core.Tests\Prism.Core.Tests.csproj", "{E0F13AA9-8083-47CA-B10D-93C5285D1505}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Prism.Events", "..\..\src\Prism.Events\Prism.Events.csproj", "{5623CB62-59C1-49BC-BB16-4C5D63D82DAC}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Prism.Events", "..\..\src\Prism.Events\Prism.Events.csproj", "{5623CB62-59C1-49BC-BB16-4C5D63D82DAC}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -95,6 +95,7 @@ Global {EE6F0C99-61D1-4E2E-8185-FBA0D246D5C7} = {E91F80AA-3D61-4C28-B876-3EDFB5921E7D} {F3D2DFDB-95FB-4CBB-A624-35EB6550854D} = {E91F80AA-3D61-4C28-B876-3EDFB5921E7D} {E0F13AA9-8083-47CA-B10D-93C5285D1505} = {E91F80AA-3D61-4C28-B876-3EDFB5921E7D} + {5623CB62-59C1-49BC-BB16-4C5D63D82DAC} = {8202B92A-A573-4365-8A15-E246504A7CBD} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {50B0D1F3-D832-4C6C-858E-24F5F3B33632} diff --git a/src/Maui/Prism.Maui/Common/MvvmHelpers.cs b/src/Maui/Prism.Maui/Common/MvvmHelpers.cs index d99a07e57c..279e5d47eb 100644 --- a/src/Maui/Prism.Maui/Common/MvvmHelpers.cs +++ b/src/Maui/Prism.Maui/Common/MvvmHelpers.cs @@ -269,13 +269,42 @@ public static void SetCurrentPageDelegate(Func getCurrentPageDelegat if (lastModal != null) page = lastModal; - return GetOnNavigatedToTargetFromChild(page); + return EvaluateCurrentPage(page); }; + private static Page EvaluateCurrentPage(Page target) + { + Page child = null; + + if (target is FlyoutPage flyout) + child = flyout.Detail; + else if (target is TabbedPage tabbed) + child = tabbed.CurrentPage; + else if (target is NavigationPage np) + child = np.Navigation.NavigationStack.Last(); + + if (child != null) + target = GetOnNavigatedToTargetFromChild(child); + + if (target is Page page) + return page.Parent switch + { + TabbedPage tab when tab.CurrentPage != target => EvaluateCurrentPage(tab.CurrentPage), + NavigationPage nav when nav.CurrentPage != target => EvaluateCurrentPage(nav.CurrentPage), + _ => target + }; + + return null; + } + public static async Task HandleNavigationPageGoBack(NavigationPage navigationPage) { var navigationService = Navigation.Xaml.Navigation.GetNavigationService(navigationPage.CurrentPage); - await navigationService.GoBackAsync(); + var result = await navigationService.GoBackAsync(); + if(result.Exception is NavigationException navEx && navEx.Message == NavigationException.CannotPopApplicationMainPage) + { + Application.Current.Quit(); + } } public static void HandleSystemGoBack(IView previousPage, IView currentPage) diff --git a/src/Maui/Prism.Maui/Controls/PrismNavigationPage.cs b/src/Maui/Prism.Maui/Controls/PrismNavigationPage.cs index 8a7a4ac6ca..33681e908d 100644 --- a/src/Maui/Prism.Maui/Controls/PrismNavigationPage.cs +++ b/src/Maui/Prism.Maui/Controls/PrismNavigationPage.cs @@ -15,8 +15,11 @@ public PrismNavigationPage(Page page) BackButtonPressed += HandleBackButtonPressed; } + /// public event EventHandler BackButtonPressed; + + /// protected override bool OnBackButtonPressed() { BackButtonPressed.Invoke(this, EventArgs.Empty); @@ -27,4 +30,4 @@ private async void HandleBackButtonPressed(object sender, EventArgs args) { await MvvmHelpers.HandleNavigationPageGoBack(this); } -} \ No newline at end of file +} diff --git a/src/Maui/Prism.Maui/Navigation/PrismWindow.cs b/src/Maui/Prism.Maui/Navigation/PrismWindow.cs index a25971b447..98e4873ed6 100644 --- a/src/Maui/Prism.Maui/Navigation/PrismWindow.cs +++ b/src/Maui/Prism.Maui/Navigation/PrismWindow.cs @@ -1,5 +1,11 @@ -using Prism.AppModel; +using System.ComponentModel; +using Prism.AppModel; using Prism.Common; +using Prism.Ioc; +using Prism.Navigation.Xaml; +using Prism.Services; +using Prism.Xaml; +using TabbedPage = Microsoft.Maui.Controls.TabbedPage; namespace Prism.Navigation; @@ -19,6 +25,56 @@ public PrismWindow(string name = DefaultWindowName) internal Page CurrentPage => Page is null ? null : MvvmHelpers.GetCurrentPage(Page); + internal bool IsRootPage => Page switch + { + TabbedPage tabbed => tabbed.CurrentPage, + NavigationPage nav => nav.RootPage, + _ => Page + } == CurrentPage; + + [EditorBrowsable(EditorBrowsableState.Never)] + public void OnSystemBack() + { + var currentPage = CurrentPage; + if(currentPage?.Parent is NavigationPage navPage) + { + // The NavigationPage has already taken care of the GoBack + return; + } + + var container = currentPage.GetContainerProvider(); + + if (IsRoot(currentPage)) + { + var app = container.Resolve() as Application; + app.Quit(); + return; + } + else if (currentPage is IDialogContainer dialogContainer) + { + if (dialogContainer.Dismiss.CanExecute(null)) + dialogContainer.Dismiss.Execute(null); + } + else + { + var navigation = container.Resolve(); + navigation.GoBackAsync(); + } + } + + private bool IsRoot(Page page) + { + if (page == Page) return true; + + return page.Parent switch + { + FlyoutPage flyout => IsRoot(flyout), + TabbedPage tabbed => IsRoot(tabbed), + NavigationPage navigation => IsRoot(navigation), + _ => false + }; + } + private async void PrismWindow_ModalPopping(object sender, ModalPoppingEventArgs e) { if (PageNavigationService.NavigationSource == PageNavigationSource.Device) diff --git a/src/Maui/Prism.Maui/PrismAppBuilder.cs b/src/Maui/Prism.Maui/PrismAppBuilder.cs index 03c1b92aff..f433b275cc 100644 --- a/src/Maui/Prism.Maui/PrismAppBuilder.cs +++ b/src/Maui/Prism.Maui/PrismAppBuilder.cs @@ -45,28 +45,23 @@ internal PrismAppBuilder(IContainerExtension containerExtension, MauiAppBuilder { var root = ContainerLocator.Container; if (root is null) - return true; + return false; var app = root.Resolve(); var windows = app.Windows.OfType(); if (!windows.Any(x => x.IsActive)) - return true; + return false; var window = windows.First(x => x.IsActive); - var currentPage = window.CurrentPage; - var container = currentPage.GetContainerProvider(); - if(currentPage is IDialogContainer dialogContainer) + if(window.IsRootPage && app is Application application) { - if (dialogContainer.Dismiss.CanExecute(null)) - dialogContainer.Dismiss.Execute(null); - } - else - { - var navigation = container.Resolve(); - navigation.GoBackAsync(); + application.Quit(); + return false; } - return false; + window.OnSystemBack(); + + return true; }); }); #endif From 73a045392f5f900945d538d5a5ac8bc0d93ad981 Mon Sep 17 00:00:00 2001 From: Dan Siegel Date: Tue, 13 Jun 2023 08:46:53 -0600 Subject: [PATCH 2/2] chore: adding xml docs --- src/Maui/Prism.Maui/Controls/PrismNavigationPage.cs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/Maui/Prism.Maui/Controls/PrismNavigationPage.cs b/src/Maui/Prism.Maui/Controls/PrismNavigationPage.cs index 33681e908d..df6b8cd7a7 100644 --- a/src/Maui/Prism.Maui/Controls/PrismNavigationPage.cs +++ b/src/Maui/Prism.Maui/Controls/PrismNavigationPage.cs @@ -2,13 +2,23 @@ namespace Prism.Controls; +/// +/// Provides a wrapper for the NavigationPage to better handle the OnBackButtonPressed event with Prism Navigation +/// public class PrismNavigationPage : NavigationPage { + /// + /// Creates a new instance of the + /// public PrismNavigationPage() { BackButtonPressed += HandleBackButtonPressed; } + /// + /// Creates a new instance of the with a specified at the Root + /// + /// public PrismNavigationPage(Page page) : base(page) { @@ -18,7 +28,6 @@ public PrismNavigationPage(Page page) /// public event EventHandler BackButtonPressed; - /// protected override bool OnBackButtonPressed() {