Browse Source

Merge pull request #3326 from AvaloniaUI/fixes/3321-item-virtualizer-clamp

Fix ItemsPresenter crash
release/0.9.0-rc.2
Jumar Macato 7 years ago
committed by Dan Walmsley
parent
commit
ec670c4048
  1. 4
      src/Avalonia.Controls/Presenters/ItemVirtualizerSimple.cs
  2. 44
      tests/Avalonia.Controls.UnitTests/ListBoxTests.cs

4
src/Avalonia.Controls/Presenters/ItemVirtualizerSimple.cs

@ -188,8 +188,8 @@ namespace Avalonia.Controls.Presenters
break; break;
case NotifyCollectionChangedAction.Remove: case NotifyCollectionChangedAction.Remove:
if (e.OldStartingIndex >= FirstIndex && if ((e.OldStartingIndex >= FirstIndex && e.OldStartingIndex < NextIndex) ||
e.OldStartingIndex < NextIndex) panel.Children.Count > ItemCount)
{ {
RecycleContainersOnRemove(); RecycleContainersOnRemove();
} }

44
tests/Avalonia.Controls.UnitTests/ListBoxTests.cs

@ -4,6 +4,7 @@
using System.Linq; using System.Linq;
using Avalonia.Collections; using Avalonia.Collections;
using Avalonia.Controls.Presenters; using Avalonia.Controls.Presenters;
using Avalonia.Controls.Primitives;
using Avalonia.Controls.Templates; using Avalonia.Controls.Templates;
using Avalonia.Input; using Avalonia.Input;
using Avalonia.LogicalTree; using Avalonia.LogicalTree;
@ -245,6 +246,23 @@ namespace Avalonia.Controls.UnitTests
Assert.Equal(false, item.IsSelected); Assert.Equal(false, item.IsSelected);
} }
[Fact]
public void Can_Decrease_Number_Of_Materialized_Items_By_Removing_From_Source_Collection()
{
var items = new AvaloniaList<string>(Enumerable.Range(0, 20).Select(x => $"Item {x}"));
var target = new ListBox
{
Template = ListBoxTemplate(),
Items = items,
ItemTemplate = new FuncDataTemplate<string>((x, _) => new TextBlock { Height = 10 })
};
Prepare(target);
target.Scroll.Offset = new Vector(0, 1);
items.RemoveRange(0, 11);
}
private void RaisePressedEvent(ListBox listBox, ListBoxItem item, MouseButton mouseButton) private void RaisePressedEvent(ListBox listBox, ListBoxItem item, MouseButton mouseButton)
{ {
_mouse.Click(listBox, item, mouseButton); _mouse.Click(listBox, item, mouseButton);
@ -383,14 +401,26 @@ namespace Avalonia.Controls.UnitTests
private FuncControlTemplate ScrollViewerTemplate() private FuncControlTemplate ScrollViewerTemplate()
{ {
return new FuncControlTemplate<ScrollViewer>((parent, scope) => return new FuncControlTemplate<ScrollViewer>((parent, scope) =>
new ScrollContentPresenter new Panel
{ {
Name = "PART_ContentPresenter", Children =
[~ScrollContentPresenter.ContentProperty] = parent.GetObservable(ScrollViewer.ContentProperty).ToBinding(), {
[~~ScrollContentPresenter.ExtentProperty] = parent[~~ScrollViewer.ExtentProperty], new ScrollContentPresenter
[~~ScrollContentPresenter.OffsetProperty] = parent[~~ScrollViewer.OffsetProperty], {
[~~ScrollContentPresenter.ViewportProperty] = parent[~~ScrollViewer.ViewportProperty], Name = "PART_ContentPresenter",
}.RegisterInNameScope(scope)); [~ScrollContentPresenter.ContentProperty] = parent.GetObservable(ScrollViewer.ContentProperty).ToBinding(),
[~~ScrollContentPresenter.ExtentProperty] = parent[~~ScrollViewer.ExtentProperty],
[~~ScrollContentPresenter.OffsetProperty] = parent[~~ScrollViewer.OffsetProperty],
[~~ScrollContentPresenter.ViewportProperty] = parent[~~ScrollViewer.ViewportProperty],
}.RegisterInNameScope(scope),
new ScrollBar
{
Name = "verticalScrollBar",
[~ScrollBar.MaximumProperty] = parent[~ScrollViewer.VerticalScrollBarMaximumProperty],
[~~ScrollBar.ValueProperty] = parent[~~ScrollViewer.VerticalScrollBarValueProperty],
}
}
});
} }
private void Prepare(ListBox target) private void Prepare(ListBox target)

Loading…
Cancel
Save