Browse Source

Fixed out of bounds in SelectionNode.

pull/3498/head
Steven Kirk 6 years ago
parent
commit
c0f34694a6
  1. 11
      src/Avalonia.Controls/SelectionNode.cs
  2. 41
      tests/Avalonia.Controls.UnitTests/SelectionModelTests.cs

11
src/Avalonia.Controls/SelectionNode.cs

@ -692,8 +692,17 @@ namespace Avalonia.Controls
if (isSelected)
{
RemoveRange(new IndexRange(index, index + count - 1), raiseOnSelectionChanged: false);
var removeRange = new IndexRange(index, index + count - 1);
SelectedCount -= IndexRange.Remove(_selected, removeRange);
selectionInvalidated = true;
if (_selectedItems != null)
{
foreach (var i in items)
{
_selectedItems.Remove(i);
}
}
}
for (int i = 0; i < _selected.Count; i++)

41
tests/Avalonia.Controls.UnitTests/SelectionModelTests.cs

@ -1481,7 +1481,7 @@ namespace Avalonia.Controls.UnitTests
}
[Fact]
public void RetainSelectionOnReset_Retains_Correct_Selection_After_Remove()
public void RetainSelectionOnReset_Retains_Correct_Selection_After_Deselect()
{
var data = new ResettingList<string> { "foo", "bar", "baz" };
var target = new SelectionModel { Source = data, RetainSelectionOnReset = true };
@ -1491,7 +1491,35 @@ namespace Avalonia.Controls.UnitTests
data.Reset();
Assert.Equal(new[] { new IndexPath(1) }, target.SelectedIndices);
Assert.Equal(new[] { "bar", }, target.SelectedItems);
Assert.Equal(new[] { "bar" }, target.SelectedItems);
}
[Fact]
public void RetainSelectionOnReset_Retains_Correct_Selection_After_Remove_1()
{
var data = new ResettingList<string> { "foo", "bar", "baz" };
var target = new SelectionModel { Source = data, RetainSelectionOnReset = true };
target.SelectRange(new IndexPath(1), new IndexPath(2));
data.RemoveAt(2);
data.Reset(new[] { "foo", "bar", "baz" });
Assert.Equal(new[] { new IndexPath(1) }, target.SelectedIndices);
Assert.Equal(new[] { "bar" }, target.SelectedItems);
}
[Fact]
public void RetainSelectionOnReset_Retains_Correct_Selection_After_Remove_2()
{
var data = new ResettingList<string> { "foo", "bar", "baz" };
var target = new SelectionModel { Source = data, RetainSelectionOnReset = true };
target.SelectRange(new IndexPath(1), new IndexPath(2));
data.RemoveAt(0);
data.Reset(new[] { "foo", "bar", "baz" });
Assert.Equal(new[] { new IndexPath(1), new IndexPath(2) }, target.SelectedIndices);
Assert.Equal(new[] { "bar", "baz" }, target.SelectedItems);
}
[Fact]
@ -1925,6 +1953,15 @@ namespace Avalonia.Controls.UnitTests
{
public event NotifyCollectionChangedEventHandler CollectionChanged;
public new void RemoveAt(int index)
{
var item = this[index];
base.RemoveAt(index);
CollectionChanged?.Invoke(
this,
new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, new[] { item }, index));
}
public void Reset(IEnumerable<object> items = null)
{
if (items != null)

Loading…
Cancel
Save