Browse Source

Merge pull request #2134 from donandren/issues/2106

fixed: scroll to last in listbox not working sometimes
Steven Kirk 7 years ago
parent
commit
b2a90f6402

+ 6 - 5
src/Avalonia.Controls/Presenters/ItemVirtualizerSimple.cs

@@ -517,7 +517,7 @@ namespace Avalonia.Controls.Presenters
 
             if (index >= 0 && index < ItemCount)
             {
-                if (index < FirstIndex)
+                if (index <= FirstIndex)
                 {
                     newOffset = index;
                 }
@@ -525,10 +525,6 @@ namespace Avalonia.Controls.Presenters
                 {
                     newOffset = index - Math.Ceiling(ViewportValue - 1);
                 }
-                else if (OffsetValue + ViewportValue >= ItemCount)
-                {
-                    newOffset = OffsetValue - 1;
-                }
 
                 if (newOffset != -1)
                 {
@@ -546,6 +542,11 @@ namespace Avalonia.Controls.Presenters
                 {
                     layoutManager.ExecuteLayoutPass();
 
+                    if (newOffset != -1 && newOffset != OffsetValue)
+                    {
+                        OffsetValue = newOffset;
+                    }
+
                     if (panel.ScrollDirection == Orientation.Vertical)
                     {
                         if (container.Bounds.Y < panel.Bounds.Y || container.Bounds.Bottom > panel.Bounds.Bottom)

+ 40 - 1
tests/Avalonia.Controls.UnitTests/Presenters/ItemsPresenterTests_Virtualization_Simple.cs

@@ -717,6 +717,45 @@ namespace Avalonia.Controls.UnitTests.Presenters
             Assert.Equal(10, target.Panel.Children.Count);
         }
 
+        [Fact]
+        public void Scroll_To_Last_Should_Work()
+        {
+            var target = CreateTarget(itemCount: 11);
+            var scroller = (TestScroller)target.Parent;
+
+            scroller.Width = scroller.Height = 100;
+            scroller.LayoutManager.ExecuteInitialLayoutPass(scroller);
+
+            var last = (target.Items as IList)[10];
+
+            target.ScrollIntoView(last);
+
+            Assert.Equal(new Vector(0, 1), ((ILogicalScrollable)target).Offset);
+            Assert.Same(target.Panel.Children[9].DataContext, last);
+        }
+
+        [Fact]
+        public void Second_Scroll_To_Last_Should_Work()
+        {
+            var target = CreateTarget(itemCount: 11);
+            var scroller = (TestScroller)target.Parent;
+
+            scroller.Width = scroller.Height = 100;
+            scroller.LayoutManager.ExecuteInitialLayoutPass(scroller);
+
+            var last = (target.Items as IList)[10];
+
+            target.ScrollIntoView(last);
+
+            Assert.Equal(new Vector(0, 1), ((ILogicalScrollable)target).Offset);
+            Assert.Same(target.Panel.Children[9].DataContext, last);
+
+            target.ScrollIntoView(last);
+
+            Assert.Equal(new Vector(0, 1), ((ILogicalScrollable)target).Offset);
+            Assert.Same(target.Panel.Children[9].DataContext, last);
+        }
+
         public class Vertical
         {
             [Fact]
@@ -1090,4 +1129,4 @@ namespace Avalonia.Controls.UnitTests.Presenters
             }
         }
     }
-}
+}