diff --git a/src/Controls/tests/TestCases.Android.Tests/snapshots/android/ShadowShouldUpdateOnCornerRadiusChange.png b/src/Controls/tests/TestCases.Android.Tests/snapshots/android/ShadowShouldUpdateOnCornerRadiusChange.png new file mode 100644 index 000000000000..0ee32b56e500 Binary files /dev/null and b/src/Controls/tests/TestCases.Android.Tests/snapshots/android/ShadowShouldUpdateOnCornerRadiusChange.png differ diff --git a/src/Controls/tests/TestCases.HostApp/Issues/Issue20596.cs b/src/Controls/tests/TestCases.HostApp/Issues/Issue20596.cs new file mode 100644 index 000000000000..493c1977c192 --- /dev/null +++ b/src/Controls/tests/TestCases.HostApp/Issues/Issue20596.cs @@ -0,0 +1,49 @@ +namespace Maui.Controls.Sample.Issues; + +[Issue(IssueTracker.Github, 20596, "[Android] Button with corner radius shadow broken on Android device", PlatformAffected.Android | PlatformAffected.UWP)] +public class Issue20596 : ContentPage +{ + public Issue20596() + { + var button = new Button + { + TextColor = Colors.Black, + HeightRequest = 200, + WidthRequest = 200, + BackgroundColor = Colors.Green, + CornerRadius = 20, + Shadow = new Shadow { Radius = 10 } + }; + + var imageButton = new ImageButton + { + HeightRequest = 200, + WidthRequest = 200, + BackgroundColor = Colors.Red, + CornerRadius = 20, + Shadow = new Shadow { Radius = 10 } + }; + + var updateButton = new Button + { + Text = "Update corner radius", + HeightRequest = 50, + AutomationId = "UpdateCornerRadiusButton" + }; + updateButton.Clicked += (sender, e) => + { + button.CornerRadius = 100; + imageButton.CornerRadius = 100; + }; + + Content = new VerticalStackLayout + { + Children = + { + button, + imageButton, + updateButton + } + }; + } +} diff --git a/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/ShadowShouldUpdateOnCornerRadiusChange.png b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/ShadowShouldUpdateOnCornerRadiusChange.png new file mode 100644 index 000000000000..29d8cc67a611 Binary files /dev/null and b/src/Controls/tests/TestCases.Mac.Tests/snapshots/mac/ShadowShouldUpdateOnCornerRadiusChange.png differ diff --git a/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue20596.cs b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue20596.cs new file mode 100644 index 000000000000..db5e319ffcb5 --- /dev/null +++ b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue20596.cs @@ -0,0 +1,23 @@ +using NUnit.Framework; +using UITest.Appium; +using UITest.Core; + +namespace Microsoft.Maui.TestCases.Tests.Issues; + +public class Issue20596 : _IssuesUITest +{ + public Issue20596(TestDevice testDevice) : base(testDevice) + { + } + + public override string Issue => "[Android] Button with corner radius shadow broken on Android device"; + + [Test] + [Category(UITestCategories.Button)] + public void ShadowShouldUpdateOnCornerRadiusChange() + { + App.WaitForElement("UpdateCornerRadiusButton"); + App.Click("UpdateCornerRadiusButton"); + VerifyScreenshot(); + } +} diff --git a/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/ShadowShouldUpdateOnCornerRadiusChange.png b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/ShadowShouldUpdateOnCornerRadiusChange.png new file mode 100644 index 000000000000..c5cc39af725a Binary files /dev/null and b/src/Controls/tests/TestCases.WinUI.Tests/snapshots/windows/ShadowShouldUpdateOnCornerRadiusChange.png differ diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios-26/ShadowShouldUpdateOnCornerRadiusChange.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios-26/ShadowShouldUpdateOnCornerRadiusChange.png new file mode 100644 index 000000000000..16b48c06eb18 Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios-26/ShadowShouldUpdateOnCornerRadiusChange.png differ diff --git a/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/ShadowShouldUpdateOnCornerRadiusChange.png b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/ShadowShouldUpdateOnCornerRadiusChange.png new file mode 100644 index 000000000000..c43ec701a9d1 Binary files /dev/null and b/src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/ShadowShouldUpdateOnCornerRadiusChange.png differ diff --git a/src/Core/src/Handlers/Button/ButtonHandler.Android.cs b/src/Core/src/Handlers/Button/ButtonHandler.Android.cs index bd69e420f11f..32d77810e857 100644 --- a/src/Core/src/Handlers/Button/ButtonHandler.Android.cs +++ b/src/Core/src/Handlers/Button/ButtonHandler.Android.cs @@ -85,6 +85,11 @@ public static void MapStrokeThickness(IButtonHandler handler, IButton button) public static void MapCornerRadius(IButtonHandler handler, IButton button) { handler.PlatformView?.UpdateCornerRadius(button); + + if (button.Shadow is not null) + { + handler.UpdateValue(nameof(IButton.Shadow)); + } } public static void MapText(IButtonHandler handler, IText button) diff --git a/src/Core/src/Handlers/Button/ButtonHandler.Windows.cs b/src/Core/src/Handlers/Button/ButtonHandler.Windows.cs index d5141a1b4edd..c0fb0f0d0fb3 100644 --- a/src/Core/src/Handlers/Button/ButtonHandler.Windows.cs +++ b/src/Core/src/Handlers/Button/ButtonHandler.Windows.cs @@ -59,6 +59,11 @@ public static void MapStrokeThickness(IButtonHandler handler, IButtonStroke butt public static void MapCornerRadius(IButtonHandler handler, IButtonStroke buttonStroke) { handler.PlatformView?.UpdateCornerRadius(buttonStroke); + + if (handler.VirtualView.Shadow is not null) + { + handler.UpdateValue(nameof(IButton.Shadow)); + } } public static void MapText(IButtonHandler handler, IText button) diff --git a/src/Core/src/Handlers/ImageButton/ImageButtonHandler.Android.cs b/src/Core/src/Handlers/ImageButton/ImageButtonHandler.Android.cs index b71e98aa8706..f127fa519806 100644 --- a/src/Core/src/Handlers/ImageButton/ImageButtonHandler.Android.cs +++ b/src/Core/src/Handlers/ImageButton/ImageButtonHandler.Android.cs @@ -62,6 +62,11 @@ public static void MapCornerRadius(IImageButtonHandler handler, IButtonStroke bu { handler.PlatformView?.UpdateCornerRadius(buttonStroke); handler.UpdateValue(nameof(IImageButton.Padding)); + + if (handler.VirtualView.Shadow is not null) + { + handler.UpdateValue(nameof(IImageButton.Shadow)); + } } public static void MapPadding(IImageButtonHandler handler, IImageButton imageButton) diff --git a/src/Core/src/Handlers/ImageButton/ImageButtonHandler.Windows.cs b/src/Core/src/Handlers/ImageButton/ImageButtonHandler.Windows.cs index 4db50de8ea3e..6148f4785ebb 100644 --- a/src/Core/src/Handlers/ImageButton/ImageButtonHandler.Windows.cs +++ b/src/Core/src/Handlers/ImageButton/ImageButtonHandler.Windows.cs @@ -88,6 +88,11 @@ public static void MapCornerRadius(IImageButtonHandler handler, IButtonStroke bu { (handler.PlatformView as Button)?.UpdateCornerRadius(buttonStroke); handler.UpdateValue(nameof(IImageButton.Padding)); + + if (handler.VirtualView.Shadow is not null) + { + handler.UpdateValue(nameof(IImageButton.Shadow)); + } } public static void MapBackground(IImageButtonHandler handler, IImageButton imageButton)