Browse Source

Fixed scrolling differently sized items.

Steven Kirk 9 years ago
parent
commit
ad9abd53c1

+ 14 - 1
src/Avalonia.Controls/Presenters/ItemVirtualizerSimple.cs

@@ -7,6 +7,7 @@ using System.Collections.Specialized;
 using System.Linq;
 using Avalonia.Controls.Utils;
 using Avalonia.Input;
+using Avalonia.Layout;
 using Avalonia.Utilities;
 
 namespace Avalonia.Controls.Presenters
@@ -210,7 +211,19 @@ namespace Avalonia.Controls.Presenters
                     InvalidateScroll();
                 }
 
-                return generator.ContainerFromIndex(newItemIndex);
+                var container = generator.ContainerFromIndex(newItemIndex);
+
+                // We need to do a layout here because it's possible that the container we moved to
+                // is only partially visible due to differing item sizes. If the container is only 
+                // partially visible, scroll again.
+                LayoutManager.Instance?.ExecuteLayoutPass();
+
+                if (!new Rect(panel.Bounds.Size).Contains(container.Bounds))
+                {
+                    OffsetValue += newItemIndex > itemIndex ? 1 : -1;
+                }
+
+                return container;
             }
 
             return null;

+ 13 - 3
src/Avalonia.SceneGraph/Rect.cs

@@ -224,14 +224,24 @@ namespace Avalonia
         }
 
         /// <summary>
-        /// Determines whether a points in in the bounds of the rectangle.
+        /// Determines whether a point in in the bounds of the rectangle.
         /// </summary>
         /// <param name="p">The point.</param>
         /// <returns>true if the point is in the bounds of the rectangle; otherwise false.</returns>
         public bool Contains(Point p)
         {
-            return p.X >= _x && p.X < _x + _width &&
-                   p.Y >= _y && p.Y < _y + _height;
+            return p.X >= _x && p.X <= _x + _width &&
+                   p.Y >= _y && p.Y <= _y + _height;
+        }
+
+        /// <summary>
+        /// Determines whether the rectangle fully contains another rectangle.
+        /// </summary>
+        /// <param name="r">The rectangle.</param>
+        /// <returns>true if the rectangle is fully contained; otherwise false.</returns>
+        public bool Contains(Rect r)
+        {
+            return Contains(r.TopLeft) && Contains(r.BottomRight);
         }
 
         /// <summary>