diff --git a/src/Controls/src/Core/Platform/GestureManager/GesturePlatformManager.Android.cs b/src/Controls/src/Core/Platform/GestureManager/GesturePlatformManager.Android.cs index 01f57405d3f0..d857503e4ac8 100644 --- a/src/Controls/src/Core/Platform/GestureManager/GesturePlatformManager.Android.cs +++ b/src/Controls/src/Core/Platform/GestureManager/GesturePlatformManager.Android.cs @@ -282,7 +282,37 @@ void OnPlatformViewTouched(object? sender, AView.TouchEventArgs e) } if (e.Event != null) + { + // Process the touch event for this view's gestures OnTouchEvent(e.Event); + + // Allow event bubbling when only drag/drop recognizers are present + // For other gestures, allow bubbling so parent behaviors (like item selection) work + if (ShouldAllowEventBubbling()) + { + e.Handled = false; + } + } + } + + bool ShouldAllowEventBubbling() + { + if (View == null) + return false; + + var recognizers = View.GetCompositeGestureRecognizers(); + if (recognizers == null || recognizers.Count == 0) + return false; + + // Don't allow bubbling if we other recognizers than drag and drop + foreach (var recognizer in recognizers) + { + if (recognizer is not DragGestureRecognizer && recognizer is not DropGestureRecognizer) + return false; + } + + // Only drag/drop recognizers present, allow bubbling + return true; } void SetupElement(VisualElement? oldElement, VisualElement? newElement) diff --git a/src/Controls/tests/TestCases.HostApp/Issues/Issue32702.xaml b/src/Controls/tests/TestCases.HostApp/Issues/Issue32702.xaml new file mode 100644 index 000000000000..18e26ebd2350 --- /dev/null +++ b/src/Controls/tests/TestCases.HostApp/Issues/Issue32702.xaml @@ -0,0 +1,36 @@ + + + + + + diff --git a/src/Controls/tests/TestCases.HostApp/Issues/Issue32702.xaml.cs b/src/Controls/tests/TestCases.HostApp/Issues/Issue32702.xaml.cs new file mode 100644 index 000000000000..28624f7f96e5 --- /dev/null +++ b/src/Controls/tests/TestCases.HostApp/Issues/Issue32702.xaml.cs @@ -0,0 +1,38 @@ +using System.Collections.ObjectModel; + +namespace Maui.Controls.Sample.Issues; + +[Issue(IssueTracker.Github, 32702, "CollectionView item selection doesn't work when DragGestureRecognizer or DropGestureRecognizer is attached to item content", PlatformAffected.Android)] +public partial class Issue32702 : ContentPage +{ + public ObservableCollection Items { get; set; } + + public Issue32702() + { + InitializeComponent(); + + Items = new ObservableCollection + { + "Item 1", + "Item 2", + "Item 3", + "Item 4", + "Item 5" + }; + + TestCollectionView.ItemsSource = Items; + } + + private void OnSelectionChanged(object sender, SelectionChangedEventArgs e) + { + if (e.CurrentSelection.Count > 0) + { + var selectedItem = e.CurrentSelection[0].ToString(); + StatusLabel.Text = $"Selected: {selectedItem}"; + } + else + { + StatusLabel.Text = "No selection"; + } + } +} diff --git a/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue32702.cs b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue32702.cs new file mode 100644 index 000000000000..67991b7a73e1 --- /dev/null +++ b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue32702.cs @@ -0,0 +1,38 @@ +using NUnit.Framework; +using UITest.Appium; +using UITest.Core; + +namespace Microsoft.Maui.TestCases.Tests.Issues; + +public class Issue32702 : _IssuesUITest +{ + public Issue32702(TestDevice device) : base(device) + { + } + + public override string Issue => "CollectionView item selection doesn't work when DragGestureRecognizer or DropGestureRecognizer is attached to item content"; + + [Test] + [Category(UITestCategories.CollectionView)] + public void CollectionViewSelectionWorksWithDragDropGestures() + { + // Wait for CollectionView to load + App.WaitForElement("TestCollectionView"); + + // Verify initial state + var statusLabel = App.WaitForElement("StatusLabel"); + Assert.That(statusLabel.GetText(), Is.EqualTo("No selection")); + + // Tap on first item + App.Tap("Item 1"); + + // Verify selection changed + Assert.That(statusLabel.GetText(), Is.EqualTo("Selected: Item 1")); + + // Tap on second item + App.Tap("Item 2"); + + // Verify selection changed again + Assert.That(statusLabel.GetText(), Is.EqualTo("Selected: Item 2")); + } +} \ No newline at end of file