Browse Source

Fix IsRegisteredAsAnchorCandidate desync, mainly affecting recycled anchors

pull/7892/head
Jade Macho 5 years ago
parent
commit
847e20150c
No known key found for this signature in database GPG Key ID: 21C91DB3ADE0B6D5
  1. 8
      src/Avalonia.Controls/Repeater/ItemsRepeater.cs
  2. 29
      src/Avalonia.Controls/Repeater/ViewportManager.cs

8
src/Avalonia.Controls/Repeater/ItemsRepeater.cs

@ -391,11 +391,7 @@ namespace Avalonia.Controls
var newBounds = element.Bounds; var newBounds = element.Bounds;
virtInfo.ArrangeBounds = newBounds; virtInfo.ArrangeBounds = newBounds;
if (!virtInfo.IsRegisteredAsAnchorCandidate) _viewportManager.RegisterScrollAnchorCandidate(element, virtInfo);
{
_viewportManager.RegisterScrollAnchorCandidate(element);
virtInfo.IsRegisteredAsAnchorCandidate = true;
}
} }
} }
@ -480,7 +476,7 @@ namespace Avalonia.Controls
_processingItemsSourceChange.Action == NotifyCollectionChangedAction.Reset); _processingItemsSourceChange.Action == NotifyCollectionChangedAction.Reset);
_viewManager.ClearElement(element, isClearedDueToCollectionChange); _viewManager.ClearElement(element, isClearedDueToCollectionChange);
_viewportManager.OnElementCleared(element); _viewportManager.OnElementCleared(element, GetVirtualizationInfo(element));
} }
private int GetElementIndexImpl(IControl element) private int GetElementIndexImpl(IControl element)

29
src/Avalonia.Controls/Repeater/ViewportManager.cs

@ -249,9 +249,10 @@ namespace Avalonia.Controls
virtInfo.IsRegisteredAsAnchorCandidate = false; virtInfo.IsRegisteredAsAnchorCandidate = false;
} }
public void OnElementCleared(IControl element) public void OnElementCleared(IControl element, VirtualizationInfo virtInfo)
{ {
_scroller?.UnregisterAnchorCandidate(element); _scroller?.UnregisterAnchorCandidate(element);
virtInfo.IsRegisteredAsAnchorCandidate = false;
} }
public void OnOwnerMeasuring() public void OnOwnerMeasuring()
@ -358,9 +359,12 @@ namespace Avalonia.Controls
{ {
foreach (var child in _owner.Children) foreach (var child in _owner.Children)
{ {
if (child != targetChild) var info = ItemsRepeater.GetVirtualizationInfo(child);
if (child != targetChild && info.IsRegisteredAsAnchorCandidate)
{ {
_scroller.UnregisterAnchorCandidate(child); _scroller.UnregisterAnchorCandidate(child);
info.IsRegisteredAsAnchorCandidate = false;
} }
} }
} }
@ -377,9 +381,13 @@ namespace Avalonia.Controls
} }
} }
public void RegisterScrollAnchorCandidate(IControl element) public void RegisterScrollAnchorCandidate(IControl element, VirtualizationInfo virtInfo)
{ {
_scroller?.RegisterAnchorCandidate(element); if (!virtInfo.IsRegisteredAsAnchorCandidate)
{
_scroller?.RegisterAnchorCandidate(element);
virtInfo.IsRegisteredAsAnchorCandidate = true;
}
} }
private IControl? GetImmediateChildOfRepeater(IControl descendant) private IControl? GetImmediateChildOfRepeater(IControl descendant)
@ -405,15 +413,18 @@ namespace Avalonia.Controls
_isBringIntoViewInProgress = false; _isBringIntoViewInProgress = false;
_makeAnchorElement = null; _makeAnchorElement = null;
// Undo the anchor deregistrations done by OnBringIntoViewRequested.
if (_scroller is object) if (_scroller is object)
{ {
foreach (var child in _owner.Children) foreach (var child in _owner.Children)
{ {
var info = ItemsRepeater.GetVirtualizationInfo(child); var info = ItemsRepeater.GetVirtualizationInfo(child);
if (info.IsRealized && info.IsHeldByLayout) // The item brought into view is still registered - don't register it more than once.
if (info.IsRealized && info.IsHeldByLayout && !info.IsRegisteredAsAnchorCandidate)
{ {
_scroller.RegisterAnchorCandidate(child); _scroller.RegisterAnchorCandidate(child);
info.IsRegisteredAsAnchorCandidate = true;
} }
} }
} }
@ -430,7 +441,13 @@ namespace Avalonia.Controls
{ {
foreach (var child in _owner.Children) foreach (var child in _owner.Children)
{ {
_scroller.UnregisterAnchorCandidate(child); var info = ItemsRepeater.GetVirtualizationInfo(child);
if (info.IsRegisteredAsAnchorCandidate)
{
_scroller.UnregisterAnchorCandidate(child);
info.IsRegisteredAsAnchorCandidate = false;
}
} }
_scroller = null; _scroller = null;

Loading…
Cancel
Save