diff --git a/.ncrunch/Sandbox.v3.ncrunchproject b/.ncrunch/Sandbox.v3.ncrunchproject
new file mode 100644
index 0000000000..319cd523ce
--- /dev/null
+++ b/.ncrunch/Sandbox.v3.ncrunchproject
@@ -0,0 +1,5 @@
+
+
+ True
+
+
\ No newline at end of file
diff --git a/src/Avalonia.Controls/Selection/SelectionModel.cs b/src/Avalonia.Controls/Selection/SelectionModel.cs
index fd27cb340a..3b5d57a7b8 100644
--- a/src/Avalonia.Controls/Selection/SelectionModel.cs
+++ b/src/Avalonia.Controls/Selection/SelectionModel.cs
@@ -242,12 +242,7 @@ namespace Avalonia.Controls.Selection
{
using var update = BatchUpdate();
var o = update.Operation;
- var range = CoerceRange(start, end);
-
- if (range.Begin == -1)
- {
- return;
- }
+ var range = new IndexRange(Math.Max(0, start), end);
if (RangesEnabled)
{
diff --git a/tests/Avalonia.Controls.UnitTests/Primitives/SelectingItemsControlTests.cs b/tests/Avalonia.Controls.UnitTests/Primitives/SelectingItemsControlTests.cs
index 192d6e0286..514d3b5475 100644
--- a/tests/Avalonia.Controls.UnitTests/Primitives/SelectingItemsControlTests.cs
+++ b/tests/Avalonia.Controls.UnitTests/Primitives/SelectingItemsControlTests.cs
@@ -1813,6 +1813,88 @@ namespace Avalonia.Controls.UnitTests.Primitives
Assert.Equal(1, raised);
}
+ [Fact]
+ public void Handles_Removing_Last_Item_In_Two_Controls_With_Bound_SelectedIndex()
+ {
+ var items = new ObservableCollection { "foo" };
+
+ // Simulates problem with TabStrip and Carousel with bound SelectedIndex.
+ var tabStrip = new TestSelector
+ {
+ Items = items,
+ SelectionMode = SelectionMode.AlwaysSelected,
+ };
+
+ var carousel = new TestSelector
+ {
+ Items = items,
+ [!Carousel.SelectedIndexProperty] = tabStrip[!TabStrip.SelectedIndexProperty],
+ };
+
+ var tabStripRaised = 0;
+ var carouselRaised = 0;
+
+ tabStrip.SelectionChanged += (s, e) =>
+ {
+ Assert.Equal(new[] { "foo" }, e.RemovedItems);
+ Assert.Empty(e.AddedItems);
+ ++tabStripRaised;
+ };
+
+ carousel.SelectionChanged += (s, e) =>
+ {
+ Assert.Equal(new[] { "foo" }, e.RemovedItems);
+ Assert.Empty(e.AddedItems);
+ ++carouselRaised;
+ };
+
+ items.RemoveAt(0);
+
+ Assert.Equal(1, tabStripRaised);
+ Assert.Equal(1, carouselRaised);
+ }
+
+ [Fact]
+ public void Handles_Removing_Last_Item_In_Controls_With_Bound_SelectedItem()
+ {
+ var items = new ObservableCollection { "foo" };
+
+ // Simulates problem with TabStrip and Carousel with bound SelectedItem.
+ var tabStrip = new TestSelector
+ {
+ Items = items,
+ SelectionMode = SelectionMode.AlwaysSelected,
+ };
+
+ var carousel = new TestSelector
+ {
+ Items = items,
+ [!Carousel.SelectedItemProperty] = tabStrip[!TabStrip.SelectedItemProperty],
+ };
+
+ var tabStripRaised = 0;
+ var carouselRaised = 0;
+
+ tabStrip.SelectionChanged += (s, e) =>
+ {
+ Assert.Equal(new[] { "foo" }, e.RemovedItems);
+ Assert.Empty(e.AddedItems);
+ ++tabStripRaised;
+ };
+
+ carousel.SelectionChanged += (s, e) =>
+ {
+ Assert.Equal(new[] { "foo" }, e.RemovedItems);
+ Assert.Empty(e.AddedItems);
+ ++carouselRaised;
+ };
+
+ items.RemoveAt(0);
+
+ Assert.Equal(1, tabStripRaised);
+ Assert.Equal(1, carouselRaised);
+ }
+
private static void Prepare(SelectingItemsControl target)
{
var root = new TestRoot