瀏覽代碼

Handle scrolling >1 page.

Steven Kirk 9 年之前
父節點
當前提交
fa3550882a

+ 4 - 3
src/Avalonia.Controls/Presenters/ItemVirtualizerSimple.cs

@@ -135,8 +135,9 @@ namespace Avalonia.Controls.Presenters
             var generator = Owner.ItemContainerGenerator;
             var selector = Owner.MemberSelector;
             var sign = delta < 0 ? -1 : 1;
-            var first = delta < 0 ? panel.Children.Count + delta : 0;
-            var count = Math.Abs(delta);
+            var move = delta < panel.Children.Count;
+            var first = delta < 0 && move ? panel.Children.Count + delta : 0;
+            var count = Math.Min(Math.Abs(delta), panel.Children.Count);
             var containers = panel.Children.GetRange(first, count).ToList();
 
             for (var i = 0; i < containers.Count; ++i)
@@ -151,7 +152,7 @@ namespace Avalonia.Controls.Presenters
                 }
             }
 
-            if (delta < panel.Children.Count)
+            if (move)
             {
                 panel.Children.RemoveRange(first, count);
 

+ 49 - 46
tests/Avalonia.Controls.UnitTests/Presenters/ItemsPresenterTests_Virtualization.cs

@@ -184,67 +184,70 @@ namespace Avalonia.Controls.UnitTests.Presenters
                 Assert.Equal(8, target.Panel.Children.Count);
             }
 
-            [Fact]
-            public void Scrolling_Less_Than_A_Page_Should_Move_Recycled_Items()
+            public class WithContainers
             {
-                var target = CreateTarget();
-                var items = (IList<string>)target.Items;
+                [Fact]
+                public void Scrolling_Less_Than_A_Page_Should_Move_Recycled_Items()
+                {
+                    var target = CreateTarget();
+                    var items = (IList<string>)target.Items;
 
-                target.ApplyTemplate();
-                target.Measure(new Size(100, 100));
-                target.Arrange(new Rect(0, 0, 100, 100));
+                    target.ApplyTemplate();
+                    target.Measure(new Size(100, 100));
+                    target.Arrange(new Rect(0, 0, 100, 100));
 
-                var containers = target.Panel.Children.ToList();
-                var scroller = (ScrollContentPresenter)target.Parent;
+                    var containers = target.Panel.Children.ToList();
+                    var scroller = (ScrollContentPresenter)target.Parent;
 
-                scroller.Offset = new Vector(0, 5);
+                    scroller.Offset = new Vector(0, 5);
 
-                var scrolledContainers = containers
-                    .Skip(5)
-                    .Take(5)
-                    .Concat(containers.Take(5)).ToList();
+                    var scrolledContainers = containers
+                        .Skip(5)
+                        .Take(5)
+                        .Concat(containers.Take(5)).ToList();
 
-                Assert.Equal(new Vector(0, 5), ((IScrollable)target).Offset);
-                Assert.Equal(scrolledContainers, target.Panel.Children);
-                
-                for (var i = 0; i < target.Panel.Children.Count; ++i)
-                {
-                    Assert.Equal(items[i + 5], target.Panel.Children[i].DataContext);
-                }
-                 
-                scroller.Offset = new Vector(0, 0);
-                Assert.Equal(new Vector(0, 0), ((IScrollable)target).Offset);
-                Assert.Equal(containers, target.Panel.Children);
+                    Assert.Equal(new Vector(0, 5), ((IScrollable)target).Offset);
+                    Assert.Equal(scrolledContainers, target.Panel.Children);
 
-                var dcs = target.Panel.Children.Select(x => x.DataContext).ToList();
+                    for (var i = 0; i < target.Panel.Children.Count; ++i)
+                    {
+                        Assert.Equal(items[i + 5], target.Panel.Children[i].DataContext);
+                    }
 
-                for (var i = 0; i < target.Panel.Children.Count; ++i)
-                {
-                    Assert.Equal(items[i], target.Panel.Children[i].DataContext);
+                    scroller.Offset = new Vector(0, 0);
+                    Assert.Equal(new Vector(0, 0), ((IScrollable)target).Offset);
+                    Assert.Equal(containers, target.Panel.Children);
+
+                    var dcs = target.Panel.Children.Select(x => x.DataContext).ToList();
+
+                    for (var i = 0; i < target.Panel.Children.Count; ++i)
+                    {
+                        Assert.Equal(items[i], target.Panel.Children[i].DataContext);
+                    }
                 }
-            }
 
-            [Fact]
-            public void Scrolling_More_Than_A_Page_Should_Recycle_Items()
-            {
-                var target = CreateTarget();
-                var items = (IList<string>)target.Items;
+                [Fact]
+                public void Scrolling_More_Than_A_Page_Should_Recycle_Items()
+                {
+                    var target = CreateTarget(itemCount: 50);
+                    var items = (IList<string>)target.Items;
 
-                target.ApplyTemplate();
-                target.Measure(new Size(100, 100));
-                target.Arrange(new Rect(0, 0, 100, 100));
+                    target.ApplyTemplate();
+                    target.Measure(new Size(100, 100));
+                    target.Arrange(new Rect(0, 0, 100, 100));
 
-                var containers = target.Panel.Children.ToList();
-                var scroller = (ScrollContentPresenter)target.Parent;
+                    var containers = target.Panel.Children.ToList();
+                    var scroller = (ScrollContentPresenter)target.Parent;
 
-                scroller.Offset = new Vector(0, 10);
+                    scroller.Offset = new Vector(0, 20);
 
-                Assert.Equal(new Vector(0, 10), ((IScrollable)target).Offset);
-                Assert.Equal(containers, target.Panel.Children);
+                    Assert.Equal(new Vector(0, 20), ((IScrollable)target).Offset);
+                    Assert.Equal(containers, target.Panel.Children);
 
-                for (var i = 0; i < target.Panel.Children.Count; ++i)
-                {
-                    Assert.Equal(items[i + 10], target.Panel.Children[i].DataContext);
+                    for (var i = 0; i < target.Panel.Children.Count; ++i)
+                    {
+                        Assert.Equal(items[i + 20], target.Panel.Children[i].DataContext);
+                    }
                 }
             }
         }