diff --git a/src/Controls/tests/DeviceTests/Xaml/StaticResourceTests.cs b/src/Controls/tests/DeviceTests/Xaml/StaticResourceTests.cs deleted file mode 100644 index f8ae44a982b6..000000000000 --- a/src/Controls/tests/DeviceTests/Xaml/StaticResourceTests.cs +++ /dev/null @@ -1,50 +0,0 @@ -using System; -using System.Diagnostics.CodeAnalysis; -using Microsoft.Maui.Controls; -using Microsoft.Maui.Controls.Xaml; -using Xunit; - -namespace Microsoft.Maui.DeviceTests; - -[Category(TestCategory.Xaml)] -public class StaticResourceTests : IDisposable -{ - [Fact("Issue #23903: Missing ControlTemplate with exception handler should throw")] - [RequiresUnreferencedCode("XAML parsing may require unreferenced code")] - public void MissingControlTemplate_WithExceptionHandler_ShouldThrow() - { - // Issue #23903: StaticResourceExtension should always throw when resource is not found, - // even when an exception handler is present (for debug/hot reload scenarios). - // This prevents the app from crashing when relaunching. - - Controls.Internals.ResourceLoader.ExceptionHandler2 = (ex) => { }; - - var xaml = """ - - - - """; - - var page = new ContentPage(); - - // Should throw an exception even with handler present - bool exceptionThrown = false; - try - { - page.LoadFromXaml(xaml); - } - catch (Exception) - { - exceptionThrown = true; - } - - Assert.True(exceptionThrown, "Expected an exception to be thrown for missing ControlTemplate"); - } - - public void Dispose() - { - Controls.Internals.ResourceLoader.ExceptionHandler2 = null; - } -} \ No newline at end of file diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/LinearGradientBrushTransparentStopsShouldNotBeOpaque.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/LinearGradientBrushTransparentStopsShouldNotBeOpaque.png new file mode 100644 index 000000000000..ca221d971695 Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/LinearGradientBrushTransparentStopsShouldNotBeOpaque.png differ diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifySearchBarHeightRequestValues.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifySearchBarHeightRequestValues.png new file mode 100644 index 000000000000..06b553735574 Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/VerifySearchBarHeightRequestValues.png differ diff --git a/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Bugzilla/Bugzilla40333.cs b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Bugzilla/Bugzilla40333.cs index 1e408e5c1b50..11ea8fc1b361 100644 --- a/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Bugzilla/Bugzilla40333.cs +++ b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Bugzilla/Bugzilla40333.cs @@ -36,10 +36,8 @@ public void ClickingOnMenuItemInRootDoesNotCrash_NavPageVersion() public void ClickingOnMenuItemInRootDoesNotCrash_TabPageVersion() { App.WaitForElement(StillHereId); -#if ANDROID || WINDOWS // On Android and Windows, two back navigation actions are needed because the back button's position is the same for both navigation and flyout pages. This requires a double navigation to return to the root page. App.TapBackArrow(); App.WaitForElement(StillHereId); -#endif App.TapBackArrow(); App.WaitForElement(StartTabPageTestId); diff --git a/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue9095.cs b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue9095.cs deleted file mode 100644 index 877bf8f6d3c2..000000000000 --- a/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue9095.cs +++ /dev/null @@ -1,81 +0,0 @@ -using NUnit.Framework; -using UITest.Appium; -using UITest.Core; - -namespace Microsoft.Maui.TestCases.Tests.Issues; - -public class Issue9095 : _IssuesUITest -{ - public Issue9095(TestDevice device) : base(device) { } - - public override string Issue => "Shell toolbar back button doesn't fire Shell.OnBackButtonPressed on Android and iOS"; - - protected override bool ResetAfterEachTest => true; - - [Test] - [Category(UITestCategories.Shell)] - public void ShellOnBackButtonPressedShouldBeInvokedWhenPressingNavigationBarBackButton() - { - // Navigate to the second page - App.WaitForElement("NavigateButton"); - App.Tap("NavigateButton"); - - // Wait for the second page to appear - App.WaitForElement("BackButtonPressedLabel"); - - // Verify the initial state - var initialText = App.FindElement("BackButtonPressedLabel").GetText(); - Assert.That(initialText, Is.EqualTo("OnBackButtonPressed Not Called"), - "Label should show 'Not Called' before pressing back."); - - var initialContentPageText = App.FindElement("ContentPageBackButtonLabel").GetText(); - Assert.That(initialContentPageText, Is.EqualTo("ContentPage OnBackButtonPressed Not Called"), - "ContentPage label should show 'Not Called' before pressing back."); - - // Tap the Shell toolbar back button - if (App is AppiumIOSApp iosApp && HelperExtensions.IsIOS26OrHigher(iosApp)) - App.TapBackArrow(); // iOS 26+ doesn't show the previous page title in the back button - else - App.TapBackArrow(Device is TestDevice.iOS or TestDevice.Mac ? "HomePage" : ""); - - // Shell.OnBackButtonPressed should have been called, updating the label. - // The second page remains visible because Shell.OnBackButtonPressed returns true. - var updatedText = App.WaitForElement("BackButtonPressedLabel").GetText(); - Assert.That(updatedText, Is.EqualTo("OnBackButtonPressed Called"), - "Shell.OnBackButtonPressed should be invoked when pressing the Shell toolbar back button."); - - // ContentPage.OnBackButtonPressed should also have been called. - var contentPageText = App.FindElement("ContentPageBackButtonLabel").GetText(); - Assert.That(contentPageText, Is.EqualTo("ContentPage OnBackButtonPressed Called"), - "ContentPage.OnBackButtonPressed should be invoked when pressing the Shell toolbar back button."); - } - - [Test] - [Category(UITestCategories.Shell)] - public void ShellOnBackButtonPressedReturnFalseShouldNavigateBack() - { - // Navigate to the return-false page - App.WaitForElement("NavigateReturnFalseButton"); - App.Tap("NavigateReturnFalseButton"); - - // Wait for the return-false page to appear - App.WaitForElement("ReturnFalsePageLabel"); - - // Tap the Shell toolbar back button - if (App is AppiumIOSApp iosApp && HelperExtensions.IsIOS26OrHigher(iosApp)) - App.TapBackArrow(); - else - App.TapBackArrow(Device is TestDevice.iOS or TestDevice.Mac ? "HomePage" : ""); - - // Shell.OnBackButtonPressed returned false, so navigation should proceed back to root. - // The labels on the root page confirm both Shell and ContentPage OnBackButtonPressed were called. - App.WaitForElement("ReturnFalseStatusLabel"); - var shellStatusText = App.FindElement("ReturnFalseStatusLabel").GetText(); - Assert.That(shellStatusText, Is.EqualTo("OnBackButtonPressed Called And Returned False"), - "Shell.OnBackButtonPressed should have been called even when returning false."); - - var contentPageStatusText = App.FindElement("ContentPageReturnFalseStatusLabel").GetText(); - Assert.That(contentPageStatusText, Is.EqualTo("ContentPage OnBackButtonPressed Called And Returned False"), - "ContentPage.OnBackButtonPressed should have been called even when returning false."); - } -} diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/LinearGradientBrushTransparentStopsShouldNotBeOpaque.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/LinearGradientBrushTransparentStopsShouldNotBeOpaque.png new file mode 100644 index 000000000000..c30ec8a0354c Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/LinearGradientBrushTransparentStopsShouldNotBeOpaque.png differ diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifySearchBarHeightRequestValues.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifySearchBarHeightRequestValues.png new file mode 100644 index 000000000000..9de7aff39216 Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/VerifySearchBarHeightRequestValues.png differ diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios-26/VerifySearchBarHeightRequestValues.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios-26/VerifySearchBarHeightRequestValues.png index 8f5f7693ec63..910d28bd0b2d 100644 Binary files a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios-26/VerifySearchBarHeightRequestValues.png and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios-26/VerifySearchBarHeightRequestValues.png differ diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios-26/VerifySearchBarPlaceholderAndBackgroundColor.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios-26/VerifySearchBarPlaceholderAndBackgroundColor.png index 1e8d006f6f17..19ba94b17f15 100644 Binary files a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios-26/VerifySearchBarPlaceholderAndBackgroundColor.png and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios-26/VerifySearchBarPlaceholderAndBackgroundColor.png differ diff --git a/src/Core/src/Handlers/ScrollView/ScrollViewHandler.Windows.cs b/src/Core/src/Handlers/ScrollView/ScrollViewHandler.Windows.cs index 42df4232f18f..40cb099774c4 100644 --- a/src/Core/src/Handlers/ScrollView/ScrollViewHandler.Windows.cs +++ b/src/Core/src/Handlers/ScrollView/ScrollViewHandler.Windows.cs @@ -38,6 +38,12 @@ protected override void ConnectHandler(ScrollViewer platformView) protected override void DisconnectHandler(ScrollViewer platformView) { + // Cascade disconnect to the PresentedContent's handler. Without this, when the + // ScrollView is restored as ContentPage.Content after being swapped out, the + // PresentedContent's native view still has a stale parent (the old ContentPanel), + // causing a WinUI COM exception "Element already has a parent" (Issue #35277). + // Cascading here ensures ToPlatform() creates a fresh native view with no parent. + VirtualView?.PresentedContent?.Handler?.DisconnectHandler(); base.DisconnectHandler(platformView); platformView.ViewChanged -= ViewChanged; } @@ -158,9 +164,6 @@ static void UpdateContentPanel(IScrollView scrollView, IScrollViewHandler handle currentPaddingLayer.CachedChildren.Clear(); } - // Detach the old handler if it exists (prevents WinUI COM exception on reuse) - scrollView.PresentedContent.Handler?.DisconnectHandler(); - var nativeContent = scrollView.PresentedContent.ToPlatform(handler.MauiContext); if (currentPaddingLayer is not null)