Browse Source

Merge pull request #858 from AvaloniaUI/fixes/849-virt-horiz-scroll

Fix horizontal scroll with virtualized items.
pull/864/head
Steven Kirk 9 years ago
committed by GitHub
parent
commit
089b505e01
  1. 5
      src/Avalonia.Controls/IVirtualizingPanel.cs
  2. 13
      src/Avalonia.Controls/Presenters/ItemVirtualizer.cs
  3. 27
      src/Avalonia.Controls/VirtualizingStackPanel.cs
  4. 18
      tests/Avalonia.Controls.UnitTests/Presenters/ItemsPresenterTests_Virtualization_Simple.cs

5
src/Avalonia.Controls/IVirtualizingPanel.cs

@ -66,6 +66,11 @@ namespace Avalonia.Controls
/// </summary>
double PixelOffset { get; set; }
/// <summary>
/// Gets or sets the current scroll offset in the cross axis.
/// </summary>
double CrossAxisOffset { get; set; }
/// <summary>
/// Invalidates the measure of the control and forces a call to
/// <see cref="IVirtualizingController.UpdateControls"/> on the next measure.

13
src/Avalonia.Controls/Presenters/ItemVirtualizer.cs

@ -206,8 +206,17 @@ namespace Avalonia.Controls.Presenters
/// <returns>The actual size used.</returns>
public virtual Size ArrangeOverride(Size finalSize)
{
var origin = Vertical ? new Point(-_crossAxisOffset, 0) : new Point(0, _crossAxisOffset);
Owner.Panel.Arrange(new Rect(origin, finalSize));
if (VirtualizingPanel != null)
{
VirtualizingPanel.CrossAxisOffset = _crossAxisOffset;
Owner.Panel.Arrange(new Rect(finalSize));
}
else
{
var origin = Vertical ? new Point(-_crossAxisOffset, 0) : new Point(0, _crossAxisOffset);
Owner.Panel.Arrange(new Rect(origin, finalSize));
}
return finalSize;
}

27
src/Avalonia.Controls/VirtualizingStackPanel.cs

@ -19,6 +19,7 @@ namespace Avalonia.Controls
private double _averageItemSize;
private int _averageCount;
private double _pixelOffset;
private double _crossAxisOffset;
private bool _forceRemeasure;
bool IVirtualizingPanel.IsFull
@ -60,6 +61,20 @@ namespace Avalonia.Controls
}
}
double IVirtualizingPanel.CrossAxisOffset
{
get { return _crossAxisOffset; }
set
{
if (_crossAxisOffset != value)
{
_crossAxisOffset = value;
InvalidateArrange();
}
}
}
private IVirtualizingController Controller => ((IVirtualizingPanel)this).Controller;
void IVirtualizingPanel.ForceInvalidateMeasure()
@ -140,7 +155,11 @@ namespace Avalonia.Controls
{
if (orientation == Orientation.Vertical)
{
rect = new Rect(rect.X, rect.Y - _pixelOffset, rect.Width, rect.Height);
rect = new Rect(
rect.X - _crossAxisOffset,
rect.Y - _pixelOffset,
rect.Width,
rect.Height);
child.Arrange(rect);
if (rect.Y >= _availableSpace.Height)
@ -157,7 +176,11 @@ namespace Avalonia.Controls
}
else
{
rect = new Rect(rect.X - _pixelOffset, rect.Y, rect.Width, rect.Height);
rect = new Rect(
rect.X - _pixelOffset,
rect.Y - _crossAxisOffset,
rect.Width,
rect.Height);
child.Arrange(rect);
if (rect.X >= _availableSpace.Width)

18
tests/Avalonia.Controls.UnitTests/Presenters/ItemsPresenterTests_Virtualization_Simple.cs

@ -786,6 +786,24 @@ namespace Avalonia.Controls.UnitTests.Presenters
Assert.Equal(new Size(10, 20), ((ILogicalScrollable)target).Extent);
Assert.Equal(new Size(5, 10), ((ILogicalScrollable)target).Viewport);
}
[Fact]
public void Horizontal_Scroll_Should_Update_Item_Position()
{
var target = CreateTarget();
target.ApplyTemplate();
target.Measure(new Size(5, 100));
target.Arrange(new Rect(0, 0, 5, 100));
((ILogicalScrollable)target).Offset = new Vector(5, 0);
target.Measure(new Size(5, 100));
target.Arrange(new Rect(0, 0, 5, 100));
Assert.Equal(new Rect(-5, 0, 10, 10), target.Panel.Children[0].Bounds);
}
}
public class Horizontal

Loading…
Cancel
Save