|
|
|
@ -19,64 +19,59 @@ namespace Avalonia.Controls.Presenters |
|
|
|
|
|
|
|
public override bool IsLogicalScrollEnabled => true; |
|
|
|
|
|
|
|
public override Size Extent |
|
|
|
{ |
|
|
|
get |
|
|
|
{ |
|
|
|
if (VirtualizingPanel.ScrollDirection == Orientation.Vertical) |
|
|
|
{ |
|
|
|
return new Size(0, Items.Count()); |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
return new Size(Items.Count(), 0); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
public override double ExtentValue => ItemCount; |
|
|
|
|
|
|
|
public override Vector Offset |
|
|
|
public override double OffsetValue |
|
|
|
{ |
|
|
|
get |
|
|
|
{ |
|
|
|
if (VirtualizingPanel.ScrollDirection == Orientation.Vertical) |
|
|
|
{ |
|
|
|
return new Vector(0, FirstIndex); |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
return new Vector(FirstIndex, 0); |
|
|
|
} |
|
|
|
var offset = VirtualizingPanel.PixelOffset > 0 ? 1 : 0; |
|
|
|
return FirstIndex + offset; |
|
|
|
} |
|
|
|
|
|
|
|
set |
|
|
|
{ |
|
|
|
var scroll = (VirtualizingPanel.ScrollDirection == Orientation.Vertical) ? |
|
|
|
value.Y : value.X; |
|
|
|
var delta = (int)(scroll - FirstIndex); |
|
|
|
var panel = VirtualizingPanel; |
|
|
|
var offset = VirtualizingPanel.PixelOffset > 0 ? 1 : 0; |
|
|
|
var delta = (int)(value - (FirstIndex + offset)); |
|
|
|
|
|
|
|
if (delta != 0) |
|
|
|
{ |
|
|
|
RecycleContainers(delta); |
|
|
|
FirstIndex += delta; |
|
|
|
LastIndex += delta; |
|
|
|
if ((NextIndex - 1) + delta < ItemCount) |
|
|
|
{ |
|
|
|
if (panel.PixelOffset > 0) |
|
|
|
{ |
|
|
|
panel.PixelOffset = 0; |
|
|
|
delta += 1; |
|
|
|
} |
|
|
|
|
|
|
|
if (delta != 0) |
|
|
|
{ |
|
|
|
RecycleContainers(delta); |
|
|
|
FirstIndex += delta; |
|
|
|
NextIndex += delta; |
|
|
|
} |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
// We're moving to a partially obscured item at the end of the list.
|
|
|
|
var firstIndex = ItemCount - panel.Children.Count; |
|
|
|
RecycleContainers(firstIndex - FirstIndex); |
|
|
|
NextIndex = ItemCount; |
|
|
|
FirstIndex = NextIndex - panel.Children.Count; |
|
|
|
panel.PixelOffset = VirtualizingPanel.PixelOverflow; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
public override Size Viewport |
|
|
|
public override double ViewportValue |
|
|
|
{ |
|
|
|
get |
|
|
|
{ |
|
|
|
var panel = VirtualizingPanel; |
|
|
|
|
|
|
|
if (panel.ScrollDirection == Orientation.Vertical) |
|
|
|
{ |
|
|
|
return new Size(0, panel.Children.Count); |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
return new Size(panel.Children.Count, 0); |
|
|
|
} |
|
|
|
// If we can't fit the last item in the panel fully, subtract 1 from the viewport.
|
|
|
|
var overflow = VirtualizingPanel.PixelOverflow > 0 ? 1 : 0; |
|
|
|
return VirtualizingPanel.Children.Count - overflow; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
@ -96,8 +91,7 @@ namespace Avalonia.Controls.Presenters |
|
|
|
// Reset indicates a large change and should (?) be quite rare.
|
|
|
|
VirtualizingPanel.Children.Clear(); |
|
|
|
Owner.ItemContainerGenerator.Clear(); |
|
|
|
FirstIndex = 0; |
|
|
|
LastIndex = -1; |
|
|
|
FirstIndex = NextIndex = 0; |
|
|
|
CreateRemoveContainers(); |
|
|
|
} |
|
|
|
|
|
|
|
@ -111,7 +105,7 @@ namespace Avalonia.Controls.Presenters |
|
|
|
|
|
|
|
if (!panel.IsFull && Items != null) |
|
|
|
{ |
|
|
|
var index = LastIndex + 1; |
|
|
|
var index = NextIndex; |
|
|
|
var items = Items.Cast<object>().Skip(index); |
|
|
|
var memberSelector = Owner.MemberSelector; |
|
|
|
|
|
|
|
@ -126,7 +120,7 @@ namespace Avalonia.Controls.Presenters |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
LastIndex = index - 1; |
|
|
|
NextIndex = index; |
|
|
|
} |
|
|
|
|
|
|
|
if (panel.OverflowCount > 0) |
|
|
|
@ -137,7 +131,7 @@ namespace Avalonia.Controls.Presenters |
|
|
|
panel.Children.RemoveRange(index, count); |
|
|
|
generator.Dematerialize(FirstIndex + index, count); |
|
|
|
|
|
|
|
LastIndex -= count; |
|
|
|
NextIndex -= count; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
@ -156,6 +150,7 @@ namespace Avalonia.Controls.Presenters |
|
|
|
{ |
|
|
|
var oldItemIndex = FirstIndex + first + i; |
|
|
|
var newItemIndex = oldItemIndex + delta + ((panel.Children.Count - count) * sign); |
|
|
|
|
|
|
|
var item = Items.ElementAt(newItemIndex); |
|
|
|
|
|
|
|
if (!generator.TryRecycle(oldItemIndex, newItemIndex, item, selector)) |
|
|
|
|