diff --git a/src/Avalonia.Controls/Presenters/ItemVirtualizerSimple.cs b/src/Avalonia.Controls/Presenters/ItemVirtualizerSimple.cs
index 381080ce4a..f9b383a928 100644
--- a/src/Avalonia.Controls/Presenters/ItemVirtualizerSimple.cs
+++ b/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;
diff --git a/src/Avalonia.SceneGraph/Rect.cs b/src/Avalonia.SceneGraph/Rect.cs
index de4d13890b..10253ec829 100644
--- a/src/Avalonia.SceneGraph/Rect.cs
+++ b/src/Avalonia.SceneGraph/Rect.cs
@@ -224,14 +224,24 @@ namespace Avalonia
}
///
- /// Determines whether a points in in the bounds of the rectangle.
+ /// Determines whether a point in in the bounds of the rectangle.
///
/// The point.
/// true if the point is in the bounds of the rectangle; otherwise false.
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;
+ }
+
+ ///
+ /// Determines whether the rectangle fully contains another rectangle.
+ ///
+ /// The rectangle.
+ /// true if the rectangle is fully contained; otherwise false.
+ public bool Contains(Rect r)
+ {
+ return Contains(r.TopLeft) && Contains(r.BottomRight);
}
///