diff --git a/src/Controls/src/Core/Compatibility/Handlers/Shell/Android/ShellToolbarTracker.cs b/src/Controls/src/Core/Compatibility/Handlers/Shell/Android/ShellToolbarTracker.cs index 202234f0c388..22a56c521573 100644 --- a/src/Controls/src/Core/Compatibility/Handlers/Shell/Android/ShellToolbarTracker.cs +++ b/src/Controls/src/Core/Compatibility/Handlers/Shell/Android/ShellToolbarTracker.cs @@ -233,6 +233,10 @@ protected async virtual void OnNavigateBack() { try { + // Call OnBackButtonPressed to allow the page to intercept navigation + if (Page?.SendBackButtonPressed() == true) + return; + await Page.Navigation.PopAsync(); } catch (Exception exc) diff --git a/src/Controls/tests/TestCases.HostApp/Issues/Issue33523.cs b/src/Controls/tests/TestCases.HostApp/Issues/Issue33523.cs new file mode 100644 index 000000000000..80ee01a99d1c --- /dev/null +++ b/src/Controls/tests/TestCases.HostApp/Issues/Issue33523.cs @@ -0,0 +1,75 @@ +using Microsoft.Maui.Controls; + +namespace Maui.Controls.Sample.Issues +{ + [Issue(IssueTracker.Github, 33523, "OnBackButtonPressed not firing for Shell Navigation Bar button in .NET 10 SR2", PlatformAffected.Android)] + public class Issue33523 : Shell + { + public Issue33523() + { + var mainPage = new ContentPage + { + Title = "Main Page", + Content = new VerticalStackLayout + { + Children = + { + new Label + { + Text = "Click the button to navigate to TestPage", + AutomationId = "MainPageLabel" + }, + new Button + { + Text = "Navigate to TestPage", + AutomationId = "NavigateButton", + Command = new Command(async () => await Shell.Current.GoToAsync("TestPage")) + } + } + } + }; + + Items.Add(new ShellContent { Content = mainPage, Route = "MainPage" }); + + Routing.RegisterRoute("TestPage", typeof(TestPage)); + } + + class TestPage : ContentPage + { + private Label _statusLabel; + + public TestPage() + { + Title = "Test Page"; + + _statusLabel = new Label + { + Text = "OnBackButtonPressed not called", + AutomationId = "StatusLabel" + }; + + Content = new VerticalStackLayout + { + Children = + { + new Label + { + Text = "Click the Navigation Bar back button (←)", + AutomationId = "InstructionLabel" + }, + _statusLabel + } + }; + } + + protected override bool OnBackButtonPressed() + { + // Update the label synchronously + _statusLabel.Text = "OnBackButtonPressed was called"; + + // Return true to prevent navigation (so we can verify the label changed) + return true; + } + } + } +} diff --git a/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue33523.cs b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue33523.cs new file mode 100644 index 000000000000..d593a69a8cbb --- /dev/null +++ b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue33523.cs @@ -0,0 +1,41 @@ +using NUnit.Framework; +using UITest.Appium; +using UITest.Core; + +namespace Microsoft.Maui.TestCases.Tests.Issues +{ + public class Issue33523 : _IssuesUITest + { + public override string Issue => "OnBackButtonPressed not firing for Shell Navigation Bar button in .NET 10 SR2"; + + public Issue33523(TestDevice device) : base(device) { } + + [Test] + [Category(UITestCategories.Shell)] + public void OnBackButtonPressedShouldFireForShellNavigationBarButton() + { + // Verify we're on the main page + App.WaitForElement("MainPageLabel"); + + // Navigate to TestPage + App.Tap("NavigateButton"); + App.WaitForElement("StatusLabel"); + + // Verify initial state + var statusLabel = App.WaitForElement("StatusLabel"); + Assert.That(statusLabel.GetText(), Is.EqualTo("OnBackButtonPressed not called")); + + // Tap the navigation bar back button + // Note: This uses the Shell's navigation bar back button, not the system back button + App.TapBackArrow(); + + // Wait a moment for the event to fire + App.WaitForElement("StatusLabel"); + + // Verify OnBackButtonPressed was called + statusLabel = App.FindElement("StatusLabel"); + Assert.That(statusLabel.GetText(), Is.EqualTo("OnBackButtonPressed was called"), + "OnBackButtonPressed should be called when tapping the Shell Navigation Bar back button"); + } + } +}