Browse Source

Handle item move and replace.

pull/9677/head
Steven Kirk 4 years ago
parent
commit
039fb905ad
  1. 5
      src/Avalonia.Controls/VirtualizingStackPanel.cs
  2. 58
      tests/Avalonia.Controls.UnitTests/VirtualizingStackPanelTests.cs

5
src/Avalonia.Controls/VirtualizingStackPanel.cs

@ -161,6 +161,11 @@ namespace Avalonia.Controls
case NotifyCollectionChangedAction.Remove:
_realizedElements.ItemsRemoved(e.OldStartingIndex, e.OldItems!.Count, _updateElementIndex, _recycleElementOnItemRemoved);
break;
case NotifyCollectionChangedAction.Replace:
case NotifyCollectionChangedAction.Move:
_realizedElements.ItemsRemoved(e.OldStartingIndex, e.OldItems!.Count, _updateElementIndex, _recycleElementOnItemRemoved);
_realizedElements.ItemsInserted(e.NewStartingIndex, e.NewItems!.Count, _updateElementIndex);
break;
case NotifyCollectionChangedAction.Reset:
_realizedElements.RecycleAllElements(_recycleElementOnItemRemoved);
break;

58
tests/Avalonia.Controls.UnitTests/VirtualizingStackPanelTests.cs

@ -141,6 +141,64 @@ namespace Avalonia.Controls.UnitTests
Assert.Equal(elements, target.GetRealizedElements());
}
[Fact]
public void Updates_Elements_On_Item_Replace()
{
using var app = App();
var (target, _, itemsControl) = CreateTarget();
var items = (ObservableCollection<string>)itemsControl.Items!;
Assert.Equal(10, target.GetRealizedElements().Count);
var toReplace = target.GetRealizedElements().ElementAt(2);
items[2] = "new";
// Container being replaced should have been recycled.
Assert.DoesNotContain(toReplace, target.GetRealizedElements());
Assert.False(toReplace!.IsVisible);
var indexes = GetRealizedIndexes(target, itemsControl);
// Item removed from realized elements at old position and space inserted at new position.
Assert.Equal(new[] { 0, 1, -1, 3, 4, 5, 6, 7, 8, 9 }, indexes);
Layout(target);
indexes = GetRealizedIndexes(target, itemsControl);
// After layout the missing container should have been created.
Assert.Equal(Enumerable.Range(0, 10), indexes);
}
[Fact]
public void Updates_Elements_On_Item_Move()
{
using var app = App();
var (target, _, itemsControl) = CreateTarget();
var items = (ObservableCollection<string>)itemsControl.Items!;
Assert.Equal(10, target.GetRealizedElements().Count);
var toMove = target.GetRealizedElements().ElementAt(2);
items.Move(2, 6);
// Container being moved should have been recycled.
Assert.DoesNotContain(toMove, target.GetRealizedElements());
Assert.False(toMove!.IsVisible);
var indexes = GetRealizedIndexes(target, itemsControl);
// Item removed from realized elements at old position and space inserted at new position.
Assert.Equal(new[] { 0, 1, 2, 3, 4, 5, -1, 7, 8, 9 }, indexes);
Layout(target);
indexes = GetRealizedIndexes(target, itemsControl);
// After layout the missing container should have been created.
Assert.Equal(Enumerable.Range(0, 10), indexes);
}
[Fact]
public void Removes_Control_Items_From_Panel_On_Item_Remove()
{

Loading…
Cancel
Save