diff --git a/src/Controls/tests/TestCases.HostApp/Issues/Issue32279.cs b/src/Controls/tests/TestCases.HostApp/Issues/Issue32279.cs new file mode 100644 index 000000000000..c35ee21626f3 --- /dev/null +++ b/src/Controls/tests/TestCases.HostApp/Issues/Issue32279.cs @@ -0,0 +1,81 @@ +namespace Maui.Controls.Sample.Issues; + +[Issue(IssueTracker.Github, 32279, "TapGestureRecognizer does not work on layouts without a Background on Windows", PlatformAffected.UWP)] +public class Issue32279 : TestContentPage +{ + const string TapAnchorNoBackground = "TapAnchorNoBackground"; + const string TapAnchorWithBackground = "TapAnchorWithBackground"; + const string ResultLabelNoBackground = "ResultLabelNoBackground"; + const string ResultLabelWithBackground = "ResultLabelWithBackground"; + + protected override void Init() + { + var layout = new StackLayout + { + Spacing = 20, + Padding = new Thickness(20) + }; + + // ContentView with NO background + var resultLabelNoBackground = new Label + { + AutomationId = ResultLabelNoBackground, + Text = "Waiting", + FontSize = 18, + }; + + var contentViewNoBackground = new ContentView + { + HeightRequest = 200, + WidthRequest = 300, + Content = new Label + { + Text = "Tap below me (no background)", + AutomationId = TapAnchorNoBackground, + VerticalOptions = LayoutOptions.Start, + HorizontalOptions = LayoutOptions.Fill, + HorizontalTextAlignment = TextAlignment.Center, + } + }; + + contentViewNoBackground.GestureRecognizers.Add(new TapGestureRecognizer + { + Command = new Command(() => resultLabelNoBackground.Text = "Tapped"), + }); + + // ContentView WITH explicit background + var resultLabelWithBackground = new Label + { + AutomationId = ResultLabelWithBackground, + Text = "Waiting", + FontSize = 18, + }; + + var contentViewWithBackground = new ContentView + { + HeightRequest = 200, + WidthRequest = 300, + BackgroundColor = Colors.LightGray, + Content = new Label + { + Text = "Tap below me (with background)", + AutomationId = TapAnchorWithBackground, + VerticalOptions = LayoutOptions.Start, + HorizontalOptions = LayoutOptions.Fill, + HorizontalTextAlignment = TextAlignment.Center, + } + }; + + contentViewWithBackground.GestureRecognizers.Add(new TapGestureRecognizer + { + Command = new Command(() => resultLabelWithBackground.Text = "Tapped"), + }); + + layout.Children.Add(contentViewNoBackground); + layout.Children.Add(resultLabelNoBackground); + layout.Children.Add(contentViewWithBackground); + layout.Children.Add(resultLabelWithBackground); + + Content = layout; + } +} \ No newline at end of file diff --git a/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue32279.cs b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue32279.cs new file mode 100644 index 000000000000..137198c9e1f2 --- /dev/null +++ b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue32279.cs @@ -0,0 +1,45 @@ +using NUnit.Framework; +using UITest.Appium; +using UITest.Core; + +namespace Microsoft.Maui.TestCases.Tests.Issues; + +public class Issue32279 : _IssuesUITest +{ + const string TapAnchorNoBackground = "TapAnchorNoBackground"; + const string TapAnchorWithBackground = "TapAnchorWithBackground"; + const string ResultLabelNoBackground = "ResultLabelNoBackground"; + const string ResultLabelWithBackground = "ResultLabelWithBackground"; + + public Issue32279(TestDevice device) : base(device) { } + + public override string Issue => "TapGestureRecognizer does not work on layouts without a Background on Windows"; + + [Test] + [Category(UITestCategories.Gestures)] + public void TapOnLayoutWithNoBackgroundShouldWork() + { + var anchor = App.WaitForElement(TapAnchorNoBackground).GetRect(); + + // Tap below the label, inside the ContentView surface + App.TapCoordinates(anchor.CenterX(), anchor.Y + anchor.Height + 50); + + var result = App.FindElement(ResultLabelNoBackground).GetText(); + + Assert.That(result, Is.EqualTo("Tapped")); + } + + [Test] + [Category(UITestCategories.Gestures)] + public void TapOnLayoutWithBackgroundShouldWork() + { + var anchor = App.WaitForElement(TapAnchorWithBackground).GetRect(); + + // Tap below the label, inside the ContentView surface + App.TapCoordinates(anchor.CenterX(), anchor.Y + anchor.Height + 50); + + var result = App.FindElement(ResultLabelWithBackground).GetText(); + + Assert.That(result, Is.EqualTo("Tapped")); + } +} \ No newline at end of file diff --git a/src/Core/src/Platform/Windows/ContentPanel.cs b/src/Core/src/Platform/Windows/ContentPanel.cs index 61c4e6677e2a..a6aa8326531b 100644 --- a/src/Core/src/Platform/Windows/ContentPanel.cs +++ b/src/Core/src/Platform/Windows/ContentPanel.cs @@ -11,6 +11,7 @@ using Microsoft.UI.Xaml; using Microsoft.UI.Xaml.Hosting; using Microsoft.UI.Xaml.Shapes; +using Microsoft.UI.Xaml.Media; namespace Microsoft.Maui.Platform { @@ -71,6 +72,9 @@ public ContentPanel() EnsureBorderPath(containsCheck: false); SizeChanged += ContentPanelSizeChanged; + + RegisterPropertyChangedCallback(BackgroundProperty, OnBackgroundPropertyChanged); + EnsureHitTestBackground(); } void ContentPanelSizeChanged(object sender, SizeChangedEventArgs e) @@ -109,6 +113,22 @@ internal void EnsureBorderPath(bool containsCheck = true) } } + static void OnBackgroundPropertyChanged(DependencyObject dependencyObject, DependencyProperty dependencyProperty) + { + if (dependencyObject is ContentPanel contentPanel) + { + contentPanel.EnsureHitTestBackground(); + } + } + + void EnsureHitTestBackground() + { + if (Background == null) + { + Background = new SolidColorBrush(UI.Colors.Transparent); + } + } + public void UpdateBackground(Paint? background) { if (_borderPath is null)