diff --git a/src/Controls/src/Core/EnumerableExtensions.cs b/src/Controls/src/Core/EnumerableExtensions.cs index e9c16b6b789b..d2915b59a6c3 100644 --- a/src/Controls/src/Core/EnumerableExtensions.cs +++ b/src/Controls/src/Core/EnumerableExtensions.cs @@ -1,64 +1,86 @@ -#nullable disable using System; using System.Collections.Generic; -using System.ComponentModel; namespace Microsoft.Maui.Controls.Internals { static class EnumerableExtensions { - public static bool HasChildGesturesFor(this IEnumerable elements, Func predicate = null) where T : GestureRecognizer + public static bool HasChildGesturesFor(this IEnumerable? elements, Func? predicate = null) where T : GestureRecognizer { - if (elements == null) + if (elements is null) + { return false; - - if (predicate == null) - predicate = x => true; + } foreach (var element in elements) + { foreach (var item in element.GestureRecognizers) { - var gesture = item as T; - if (gesture != null && predicate(gesture)) + if (item is T gesture && (predicate is null || predicate(gesture))) + { return true; + } } + } return false; } - public static IEnumerable GetChildGesturesFor(this IEnumerable elements, Func predicate = null) where T : GestureRecognizer + public static IEnumerable GetChildGesturesFor(this IEnumerable? elements, Func? predicate = null) where T : GestureRecognizer { - if (elements == null) + if (elements is null) + { yield break; - - if (predicate == null) - predicate = x => true; + } foreach (var element in elements) + { foreach (var item in element.GestureRecognizers) { - var gesture = item as T; - if (gesture != null && predicate(gesture)) + if (item is T gesture && (predicate is null || predicate(gesture))) + { yield return gesture; + } } + } } - public static IEnumerable GetGesturesFor(this IEnumerable gestures, Func predicate = null) where T : GestureRecognizer + /// The method makes a defensive copy of the gestures. + public static IEnumerable GetGesturesFor(this IEnumerable? gestures, Func? predicate = null) where T : GestureRecognizer { - if (gestures == null) + if (gestures is null) + { yield break; - - if (predicate == null) - predicate = x => true; + } foreach (IGestureRecognizer item in new List(gestures)) { - var gesture = item as T; - if (gesture != null && predicate(gesture)) + if (item is T gesture && (predicate is null || predicate(gesture))) { yield return gesture; } } } + + internal static bool HasAnyGesturesFor(this IEnumerable? gestures, Func? predicate = null) where T : GestureRecognizer + => FirstGestureOrDefault(gestures, predicate) is not null; + + internal static T? FirstGestureOrDefault(this IEnumerable? gestures, Func? predicate = null) where T : GestureRecognizer + { + if (gestures is null) + { + return null; + } + + foreach (IGestureRecognizer item in gestures) + { + if (item is T gesture && (predicate is null || predicate(gesture))) + { + return gesture; + } + } + + return null; + } } } diff --git a/src/Controls/src/Core/Platform/GestureManager/GesturePlatformManager.Windows.cs b/src/Controls/src/Core/Platform/GestureManager/GesturePlatformManager.Windows.cs index 939d240462b1..a59ff797e33a 100644 --- a/src/Controls/src/Core/Platform/GestureManager/GesturePlatformManager.Windows.cs +++ b/src/Controls/src/Core/Platform/GestureManager/GesturePlatformManager.Windows.cs @@ -670,28 +670,32 @@ void PinchComplete(bool success) void UpdateDragAndDropGestureRecognizers() { - if (_container == null) + if (_container is null) + { return; + } var view = Element as View; IList? gestures = view?.GestureRecognizers; - if (gestures == null) + if (gestures is null) + { return; + } - _container.CanDrag = gestures.GetGesturesFor() - .FirstOrDefault()?.CanDrag ?? false; + bool canDrag = gestures.FirstGestureOrDefault()?.CanDrag ?? false; + _container.CanDrag = canDrag; - _container.AllowDrop = gestures.GetGesturesFor() - .FirstOrDefault()?.AllowDrop ?? false; + bool allowDrop = gestures.FirstGestureOrDefault()?.AllowDrop ?? false; + _container.AllowDrop = allowDrop; - if (_container.CanDrag) + if (canDrag) { _container.DragStarting += HandleDragStarting; _container.DropCompleted += HandleDropCompleted; } - if (_container.AllowDrop) + if (allowDrop) { _container.DragOver += HandleDragOver; _container.Drop += HandleDrop; @@ -714,7 +718,7 @@ void UpdatingGestureRecognizers() IList? childGestures = children?.GetChildGesturesFor().ToList(); - if (gestures.GetGesturesFor(g => g.NumberOfTapsRequired == 1).Any() + if (gestures.HasAnyGesturesFor(g => g.NumberOfTapsRequired == 1) || children?.GetChildGesturesFor(g => g.NumberOfTapsRequired == 1).Any() == true) { _container.Tapped += OnTap; @@ -728,7 +732,7 @@ void UpdatingGestureRecognizers() } } - if (gestures.GetGesturesFor(g => g.NumberOfTapsRequired == 1 || g.NumberOfTapsRequired == 2).Any() + if (gestures.HasAnyGesturesFor(g => g.NumberOfTapsRequired == 1 || g.NumberOfTapsRequired == 2) || children?.GetChildGesturesFor(g => g.NumberOfTapsRequired == 1 || g.NumberOfTapsRequired == 2).Any() == true) { _container.DoubleTapped += OnTap; @@ -747,11 +751,13 @@ void UpdatingGestureRecognizers() _container.PointerPressed += OnPgrPointerPressed; _container.PointerReleased += OnPgrPointerReleased; - bool hasSwipeGesture = gestures.GetGesturesFor().GetEnumerator().MoveNext(); - bool hasPinchGesture = gestures.GetGesturesFor().GetEnumerator().MoveNext(); - bool hasPanGesture = gestures.GetGesturesFor().GetEnumerator().MoveNext(); + bool hasSwipeGesture = gestures.HasAnyGesturesFor(); + bool hasPinchGesture = gestures.HasAnyGesturesFor(); + bool hasPanGesture = gestures.HasAnyGesturesFor(); if (!hasSwipeGesture && !hasPinchGesture && !hasPanGesture) + { return; + } //We can't handle ManipulationMode.Scale and System , so we don't support pinch/pan on a scrollview if (Element is ScrollView)