Browse Source

Avoid reset of containers when anchor element is replaced in ItemsRepeater.

* avoid reset of containers when anchor element is replaced

* fix element 0 ownership issue

Ported from e45e83d010
pull/2603/head
Steven Kirk 7 years ago
parent
commit
cd04e768f0
  1. 34
      src/Avalonia.Layout/ElementManager.cs
  2. 4
      src/Avalonia.Layout/UniformGridLayout.cs
  3. 7
      src/Avalonia.Layout/UniformGridLayoutState.cs

34
src/Avalonia.Layout/ElementManager.cs

@ -276,8 +276,38 @@ namespace Avalonia.Layout
case NotifyCollectionChangedAction.Replace:
{
OnItemsRemoved(args.OldStartingIndex, args.OldItems.Count);
OnItemsAdded(args.NewStartingIndex, args.NewItems.Count);
int oldSize = args.OldItems.Count;
int newSize = args.NewItems.Count;
int oldStartIndex = args.OldStartingIndex;
int newStartIndex = args.NewStartingIndex;
if (oldSize == newSize &&
oldStartIndex == newStartIndex &&
IsDataIndexRealized(oldStartIndex) &&
IsDataIndexRealized(oldStartIndex + oldSize -1))
{
// Straight up replace of n items within the realization window.
// Removing and adding might causes us to lose the anchor causing us
// to throw away all containers and start from scratch.
// Instead, we can just clear those items and set the element to
// null (sentinel) and let the next measure get new containers for them.
var startRealizedIndex = GetRealizedRangeIndexFromDataIndex(oldStartIndex);
for (int realizedIndex = startRealizedIndex; realizedIndex < startRealizedIndex + oldSize; realizedIndex++)
{
var elementRef = _realizedElements[realizedIndex];
if (elementRef != null)
{
_context.RecycleElement(elementRef);
_realizedElements[realizedIndex] = null;
}
}
}
else
{
OnItemsRemoved(oldStartIndex, oldSize);
OnItemsAdded(newStartIndex, newSize);
}
}
break;

4
src/Avalonia.Layout/UniformGridLayout.cs

@ -409,6 +409,10 @@ namespace Avalonia.Layout
_orientation.ScrollOrientation,
LayoutId);
// If after Measure the first item is in the realization rect, then we revoke grid state's ownership,
// and only use the layout when to clear it when it's done.
gridState.EnsureFirstElementOwnership(context);
return new Size(desiredSize.Width, desiredSize.Height);
}

7
src/Avalonia.Layout/UniformGridLayoutState.cs

@ -134,10 +134,13 @@ namespace Avalonia.Layout
}
}
internal void EnsureFirstElementOwnership()
internal void EnsureFirstElementOwnership(VirtualizingLayoutContext context)
{
if (FlowAlgorithm.GetElementIfRealized(0) != null)
if (_cachedFirstElement != null && FlowAlgorithm.GetElementIfRealized(0) != null)
{
// We created the element, but then flowlayout algorithm took ownership, so we can clear it and
// let flowlayout algorithm do its thing.
context.RecycleElement(_cachedFirstElement);
_cachedFirstElement = null;
}
}

Loading…
Cancel
Save