diff --git a/src/Avalonia.Controls/Primitives/SelectingItemsControl.cs b/src/Avalonia.Controls/Primitives/SelectingItemsControl.cs index 30a6ce07ea..5f8c5da2f8 100644 --- a/src/Avalonia.Controls/Primitives/SelectingItemsControl.cs +++ b/src/Avalonia.Controls/Primitives/SelectingItemsControl.cs @@ -423,6 +423,11 @@ namespace Avalonia.Controls.Primitives _selection.Clear(); } } + else if (change.Property == SelectionModeProperty && _selection is object) + { + var newValue = change.NewValue.GetValueOrDefault(); + _selection.SingleSelect = !newValue.HasFlagCustom(SelectionMode.Multiple); + } } /// diff --git a/src/Avalonia.Controls/Selection/SelectionModel.cs b/src/Avalonia.Controls/Selection/SelectionModel.cs index f34a358925..7ce2624d02 100644 --- a/src/Avalonia.Controls/Selection/SelectionModel.cs +++ b/src/Avalonia.Controls/Selection/SelectionModel.cs @@ -45,6 +45,14 @@ namespace Avalonia.Controls.Selection { if (_singleSelect != value) { + if (value == true) + { + using var update = BatchUpdate(); + var selectedIndex = SelectedIndex; + Clear(); + SelectedIndex = selectedIndex; + } + _singleSelect = value; RangesEnabled = !value; diff --git a/tests/Avalonia.Controls.UnitTests/Primitives/SelectingItemsControlTests.cs b/tests/Avalonia.Controls.UnitTests/Primitives/SelectingItemsControlTests.cs index 793d273fb2..33744949c3 100644 --- a/tests/Avalonia.Controls.UnitTests/Primitives/SelectingItemsControlTests.cs +++ b/tests/Avalonia.Controls.UnitTests/Primitives/SelectingItemsControlTests.cs @@ -7,6 +7,7 @@ using System.Linq; using Avalonia.Collections; using Avalonia.Controls.Presenters; using Avalonia.Controls.Primitives; +using Avalonia.Controls.Selection; using Avalonia.Controls.Templates; using Avalonia.Data; using Avalonia.Input; @@ -1321,6 +1322,19 @@ namespace Avalonia.Controls.UnitTests.Primitives Assert.Equal(1, target.SelectedIndex); } + [Fact] + public void Setting_SelectionMode_Should_Update_SelectionModel() + { + var target = new TestSelector(); + var model = target.Selection; + + Assert.True(model.SingleSelect); + + target.SelectionMode = SelectionMode.Multiple; + + Assert.False(model.SingleSelect); + } + private static void Prepare(SelectingItemsControl target) { var root = new TestRoot @@ -1401,6 +1415,18 @@ namespace Avalonia.Controls.UnitTests.Primitives SelectionMode = selectionMode; } + public new ISelectionModel Selection + { + get => base.Selection; + set => base.Selection = value; + } + + public new SelectionMode SelectionMode + { + get => base.SelectionMode; + set => base.SelectionMode = value; + } + public new bool MoveSelection(NavigationDirection direction, bool wrap) { return base.MoveSelection(direction, wrap); diff --git a/tests/Avalonia.Controls.UnitTests/Selection/SelectionModelTests_Multiple.cs b/tests/Avalonia.Controls.UnitTests/Selection/SelectionModelTests_Multiple.cs index e40c2ebf09..3640faf7cb 100644 --- a/tests/Avalonia.Controls.UnitTests/Selection/SelectionModelTests_Multiple.cs +++ b/tests/Avalonia.Controls.UnitTests/Selection/SelectionModelTests_Multiple.cs @@ -712,6 +712,54 @@ namespace Avalonia.Controls.UnitTests.Selection } } + public class SingleSelect + { + [Fact] + public void Converting_To_Single_Selection_Removes_Multiple_Selection() + { + var target = CreateTarget(); + var raised = 0; + + target.SelectRange(1, 3); + + target.SelectionChanged += (s, e) => + { + Assert.Equal(new[] { 2, 3 }, e.DeselectedIndexes); + Assert.Equal(new[] { "baz", "qux" }, e.DeselectedItems); + Assert.Empty(e.SelectedIndexes); + Assert.Empty(e.SelectedItems); + ++raised; + }; + + target.SingleSelect = true; + + Assert.Equal(1, target.SelectedIndex); + Assert.Equal(new[] { 1 }, target.SelectedIndexes); + Assert.Equal("bar", target.SelectedItem); + Assert.Equal(new[] { "bar" }, target.SelectedItems); + Assert.Equal(1, raised); + } + + [Fact] + public void Raises_PropertyChanged() + { + var target = CreateTarget(); + var raised = 0; + + target.PropertyChanged += (s, e) => + { + if (e.PropertyName == nameof(target.SingleSelect)) + { + ++raised; + } + }; + + target.SingleSelect = true; + + Assert.Equal(1, raised); + } + } + public class CollectionChanges { [Fact]