From 1fc35d90c04d204f4991dea18bba4e119b076fbf Mon Sep 17 00:00:00 2001 From: ClemensFischer Date: Mon, 17 Mar 2025 10:56:42 +0100 Subject: [PATCH] Range selection in MapItemsControl --- MapControl/Avalonia/MapItem.Avalonia.cs | 4 +-- MapControl/Shared/MapItemsControl.cs | 37 +++++++++++++++++++++++++ MapControl/WPF/MapItem.WPF.cs | 5 ++-- MapControl/WinUI/MapItem.WinUI.cs | 4 +-- 4 files changed, 41 insertions(+), 9 deletions(-) diff --git a/MapControl/Avalonia/MapItem.Avalonia.cs b/MapControl/Avalonia/MapItem.Avalonia.cs index 64fb4648..58eaba56 100644 --- a/MapControl/Avalonia/MapItem.Avalonia.cs +++ b/MapControl/Avalonia/MapItem.Avalonia.cs @@ -9,14 +9,12 @@ DependencyPropertyHelper.AddOwner(MapPanel.LocationProperty, null, (item, oldValue, newValue) => item.UpdateMapTransform(newValue)); - /// - /// Prevent range selection by Shift+PointerPressed. - /// protected override void OnPointerPressed(PointerPressedEventArgs e) { if (e.KeyModifiers.HasFlag(KeyModifiers.Shift)) { e.Handled = true; + MapItemsControl.SetSelectedItemsRange(this); } else { diff --git a/MapControl/Shared/MapItemsControl.cs b/MapControl/Shared/MapItemsControl.cs index 88229075..7f2f4c66 100644 --- a/MapControl/Shared/MapItemsControl.cs +++ b/MapControl/Shared/MapItemsControl.cs @@ -78,5 +78,42 @@ namespace MapControl { SelectItemsByPosition(rect.Contains); } + + internal static void SetSelectedItemsRange(MapItem mapItem) + { + if (ItemsControlFromItemContainer(mapItem) is MapItemsControl mapItemsControl && + mapItemsControl.SelectionMode != SelectionMode.Single) + { + var pos = MapPanel.GetViewPosition(mapItem); + + if (pos.HasValue) + { + var xMin = pos.Value.X; + var xMax = pos.Value.X; + var yMin = pos.Value.Y; + var yMax = pos.Value.Y; + + if (mapItemsControl.SelectedItem != null) + { + var selectedMapItem = mapItemsControl.ContainerFromItem(mapItemsControl.SelectedItem); + + if (selectedMapItem != mapItem) + { + pos = MapPanel.GetViewPosition(selectedMapItem); + + if (pos.HasValue) + { + xMin = Math.Min(xMin, pos.Value.X); + xMax = Math.Max(xMax, pos.Value.X); + yMin = Math.Min(yMin, pos.Value.Y); + yMax = Math.Max(yMax, pos.Value.Y); + } + } + } + + mapItemsControl.SelectItemsInRect(new Rect(xMin, yMin, xMax - xMin, yMax - yMin)); + } + } + } } } diff --git a/MapControl/WPF/MapItem.WPF.cs b/MapControl/WPF/MapItem.WPF.cs index acb86147..a48d326f 100644 --- a/MapControl/WPF/MapItem.WPF.cs +++ b/MapControl/WPF/MapItem.WPF.cs @@ -1,4 +1,5 @@ using System.Windows; +using System.Windows.Controls; using System.Windows.Input; namespace MapControl @@ -17,14 +18,12 @@ namespace MapControl DefaultStyleKeyProperty.OverrideMetadata(typeof(MapItem), new FrameworkPropertyMetadata(typeof(MapItem))); } - /// - /// Prevent range selection by Shift+MouseLeftButtonDown. - /// protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e) { if (Keyboard.Modifiers.HasFlag(ModifierKeys.Shift)) { e.Handled = true; + MapItemsControl.SetSelectedItemsRange(this); } else { diff --git a/MapControl/WinUI/MapItem.WinUI.cs b/MapControl/WinUI/MapItem.WinUI.cs index 0f775a73..4015093c 100644 --- a/MapControl/WinUI/MapItem.WinUI.cs +++ b/MapControl/WinUI/MapItem.WinUI.cs @@ -31,14 +31,12 @@ namespace MapControl MapPanel.InitMapElement(this); } - /// - /// Prevent range selection by Shift+PointerPressed. - /// protected override void OnPointerPressed(PointerRoutedEventArgs e) { if (e.KeyModifiers.HasFlag(VirtualKeyModifiers.Shift)) { e.Handled = true; + MapItemsControl.SetSelectedItemsRange(this); } else {