From 3858a7214b19e98f08baaa156deef6075a8d4042 Mon Sep 17 00:00:00 2001 From: Brubning Date: Thu, 12 Sep 2024 04:01:29 +0100 Subject: [PATCH] Allow selection of multiple consecutive blocks in SelectingItemsControl. (#16907) * Stop Selection.Clear() when selecting a range to enable multiple consecutive blocks to be selected. * Reinstated Selection.Clear() when range is true and toggleModifier is false. When range and toggleModifier are true, consecutive ranges are selected. Added new unit test. --- .../Primitives/SelectingItemsControl.cs | 5 +++- .../ListBoxTests_Multiple.cs | 30 +++++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/src/Avalonia.Controls/Primitives/SelectingItemsControl.cs b/src/Avalonia.Controls/Primitives/SelectingItemsControl.cs index 202f4e0252c..636b4bd576c 100644 --- a/src/Avalonia.Controls/Primitives/SelectingItemsControl.cs +++ b/src/Avalonia.Controls/Primitives/SelectingItemsControl.cs @@ -817,7 +817,10 @@ protected void UpdateSelection( else if (range) { using var operation = Selection.BatchUpdate(); - Selection.Clear(); + if (!toggleModifier) + { + Selection.Clear(); + } Selection.SelectRange(Selection.AnchorIndex, index); } else if (!fromFocus && toggle) diff --git a/tests/Avalonia.Controls.UnitTests/ListBoxTests_Multiple.cs b/tests/Avalonia.Controls.UnitTests/ListBoxTests_Multiple.cs index 18636810304..107ce4d33f4 100644 --- a/tests/Avalonia.Controls.UnitTests/ListBoxTests_Multiple.cs +++ b/tests/Avalonia.Controls.UnitTests/ListBoxTests_Multiple.cs @@ -167,6 +167,36 @@ public void Ctrl_Selecting_Non_SelectedItem_With_Multiple_Selection_Active_Leave } } + [Fact] + public void ToggleModifier_And_Range_Should_Select_Second_Range() + { + using (UnitTestApplication.Start(TestServices.MockPlatformRenderInterface)) + { + var target = new ListBox + { + Template = new FuncControlTemplate(CreateListBoxTemplate), + ItemsSource = new[] { "Foo", "Bar", "Baz", "Gap", "Boo", "Far", "Faz" }, + SelectionMode = SelectionMode.Multiple, + Width = 100, + Height = 100, + }; + + var root = new TestRoot(target); + root.LayoutManager.ExecuteInitialLayoutPass(); + + AvaloniaLocator.CurrentMutable.Bind().ToConstant(new PlatformHotkeyConfiguration()); + // Select first range + _helper.Click(target.Presenter.Panel.Children[0]); + _helper.Click(target.Presenter.Panel.Children[2], modifiers: KeyModifiers.Shift); + + // Select second range + _helper.Click(target.Presenter.Panel.Children[4], modifiers: KeyModifiers.Control); + _helper.Click(target.Presenter.Panel.Children[6], modifiers: KeyModifiers.Control | KeyModifiers.Shift); + + Assert.Equal(new[] { "Foo", "Bar", "Baz", "Boo", "Far", "Faz" }, target.SelectedItems); + } + } + [Fact] public void Should_Ctrl_Select_Correct_Item_When_Duplicate_Items_Are_Present() {