From 3d5a52113a61c9438ef2c4d754702c398b66041f Mon Sep 17 00:00:00 2001 From: ClemensFischer Date: Tue, 14 Apr 2026 11:52:32 +0200 Subject: [PATCH] Unified WinUI and Avalonia MapItem selection --- MapControl/Avalonia/Map.Avalonia.cs | 2 - MapControl/Avalonia/MapItem.Avalonia.cs | 45 +++++++++++++++++++ .../Avalonia/MapItemsControl.Avalonia.cs | 14 +++--- MapControl/WinUI/MapItem.WinUI.cs | 21 ++++++--- 4 files changed, 66 insertions(+), 16 deletions(-) create mode 100644 MapControl/Avalonia/MapItem.Avalonia.cs diff --git a/MapControl/Avalonia/Map.Avalonia.cs b/MapControl/Avalonia/Map.Avalonia.cs index 4963e868..49b55bc3 100644 --- a/MapControl/Avalonia/Map.Avalonia.cs +++ b/MapControl/Avalonia/Map.Avalonia.cs @@ -67,8 +67,6 @@ public partial class Map point.Pointer.Type == PointerType.Touch && ManipulationMode != ManipulationModes.None) { - point.Pointer.Capture(this); - if (pointer1 == null) { pointer1 = point.Pointer; diff --git a/MapControl/Avalonia/MapItem.Avalonia.cs b/MapControl/Avalonia/MapItem.Avalonia.cs new file mode 100644 index 00000000..93ffd69a --- /dev/null +++ b/MapControl/Avalonia/MapItem.Avalonia.cs @@ -0,0 +1,45 @@ +using Avalonia; +using Avalonia.Input; +using System; + +namespace MapControl; + +public partial class MapItem +{ + Point? pointerPressedPosition; + + protected override void OnPointerPressed(PointerPressedEventArgs e) + { + base.OnPointerPressed(e); + + var point = e.GetCurrentPoint(null); + + if (point.Properties.IsLeftButtonPressed) + { + pointerPressedPosition = point.Position; + } + + e.Handled = true; + } + + protected override void OnPointerReleased(PointerReleasedEventArgs e) + { + if (pointerPressedPosition.HasValue) + { + const double pointerMovementThreshold = 2d; + var position = e.GetCurrentPoint(null).Position; + + // Perform selection only when no significant pointer movement occured. + // + if (Math.Abs(position.X - pointerPressedPosition.Value.X) <= pointerMovementThreshold && + Math.Abs(position.Y - pointerPressedPosition.Value.Y) <= pointerMovementThreshold) + { + base.OnPointerReleased(e); + } + + pointerPressedPosition = null; + } + + e.Handled = true; + } +} diff --git a/MapControl/Avalonia/MapItemsControl.Avalonia.cs b/MapControl/Avalonia/MapItemsControl.Avalonia.cs index 7a16324e..08bf009a 100644 --- a/MapControl/Avalonia/MapItemsControl.Avalonia.cs +++ b/MapControl/Avalonia/MapItemsControl.Avalonia.cs @@ -54,22 +54,22 @@ public partial class MapItemsControl ClearContainer((MapItem)container); } - protected override bool ShouldTriggerSelection(Visual selectable, PointerEventArgs eventArgs) + protected override bool ShouldTriggerSelection(Visual selectable, PointerEventArgs e) { - return eventArgs.Pointer.Type != PointerType.Mouse || - eventArgs.Properties.PointerUpdateKind == PointerUpdateKind.LeftButtonReleased; + return e.Properties.PointerUpdateKind == PointerUpdateKind.LeftButtonReleased; } - public override bool UpdateSelectionFromEvent(UIElement container, RoutedEventArgs eventArgs) + public override bool UpdateSelectionFromEvent(UIElement container, RoutedEventArgs e) { if (SelectionMode == SelectionMode.Multiple && - eventArgs is PointerEventArgs pointerEventArgs && - pointerEventArgs.KeyModifiers.HasFlag(KeyModifiers.Shift)) + e is PointerEventArgs p && + p.KeyModifiers.HasFlag(KeyModifiers.Shift) && + ShouldTriggerSelection(container, p)) { SelectItemsInRange((MapItem)container); return true; } - return base.UpdateSelectionFromEvent(container, eventArgs); + return base.UpdateSelectionFromEvent(container, e); } } diff --git a/MapControl/WinUI/MapItem.WinUI.cs b/MapControl/WinUI/MapItem.WinUI.cs index 45441d64..17a7461d 100644 --- a/MapControl/WinUI/MapItem.WinUI.cs +++ b/MapControl/WinUI/MapItem.WinUI.cs @@ -27,7 +27,14 @@ public partial class MapItem protected override void OnPointerPressed(PointerRoutedEventArgs e) { base.OnPointerPressed(e); - pointerPressedPosition = e.GetCurrentPoint(null).Position; + + var point = e.GetCurrentPoint(null); + + if (point.Properties.IsLeftButtonPressed) + { + pointerPressedPosition = point.Position; + } + e.Handled = true; } @@ -35,16 +42,16 @@ public partial class MapItem { if (pointerPressedPosition.HasValue) { - const float pointerMovementThreshold = 2f; - var p = e.GetCurrentPoint(null).Position; + const double pointerMovementThreshold = 2d; + var position = e.GetCurrentPoint(null).Position; // Perform selection only when no significant pointer movement occured. // - if (Math.Abs(p.X - pointerPressedPosition.Value.X) <= pointerMovementThreshold && - Math.Abs(p.Y - pointerPressedPosition.Value.Y) <= pointerMovementThreshold && - ItemsControl.ItemsControlFromItemContainer(this) is MapItemsControl mapItemsControl) + if (Math.Abs(position.X - pointerPressedPosition.Value.X) <= pointerMovementThreshold && + Math.Abs(position.Y - pointerPressedPosition.Value.Y) <= pointerMovementThreshold) { - if (mapItemsControl.SelectionMode == SelectionMode.Extended && + if (ItemsControl.ItemsControlFromItemContainer(this) is MapItemsControl mapItemsControl && + mapItemsControl.SelectionMode == SelectionMode.Extended && e.KeyModifiers.HasFlag(VirtualKeyModifiers.Shift)) { mapItemsControl.SelectItemsInRange(this);