diff --git a/src/Avalonia.Controls/Repeater/ViewManager.cs b/src/Avalonia.Controls/Repeater/ViewManager.cs index 8906b9f577..ee800cffc4 100644 --- a/src/Avalonia.Controls/Repeater/ViewManager.cs +++ b/src/Avalonia.Controls/Repeater/ViewManager.cs @@ -110,10 +110,28 @@ namespace Avalonia.Controls } } + // We need to clear the datacontext to prevent crashes from happening, + // however we only do that if we were the ones setting it. + // That is when one of the following is the case (numbering taken from line ~642): + // 1.2 No ItemTemplate, data is not a UIElement + // 2.1 ItemTemplate, data is not FrameworkElement + // 2.2.2 Itemtemplate, data is FrameworkElement, ElementFactory returned Element different to data + // + // In all of those three cases, we the ItemTemplateShim is NOT null. + // Luckily when we create the items, we store whether we were the once setting the DataContext. public void ClearElementToElementFactory(IControl element) { _owner.OnElementClearing(element); + var virtInfo = ItemsRepeater.GetVirtualizationInfo(element); + virtInfo.MoveOwnershipToElementFactory(); + + // During creation of this object, we were the one setting the DataContext, so clear it now. + if (virtInfo.MustClearDataContext) + { + element.DataContext = null; + } + if (_owner.ItemTemplateShim != null) { _owner.ItemTemplateShim.RecycleElement(_owner, element); @@ -127,9 +145,6 @@ namespace Avalonia.Controls } } - var virtInfo = ItemsRepeater.GetVirtualizationInfo(element); - virtInfo.MoveOwnershipToElementFactory(); - if (_lastFocusedElement == element) { // Focused element is going away. Remove the tracked last focused element @@ -597,11 +612,14 @@ namespace Avalonia.Controls { virtInfo = ItemsRepeater.CreateAndInitializeVirtualizationInfo(element); } + // Clear flag + virtInfo.MustClearDataContext = false; if (data != element) { // Prepare the element element.DataContext = data; + virtInfo.MustClearDataContext = true; } virtInfo.MoveOwnershipToLayoutFromElementFactory( diff --git a/src/Avalonia.Controls/Repeater/VirtualizationInfo.cs b/src/Avalonia.Controls/Repeater/VirtualizationInfo.cs index eb30c1b7cf..7a639419c1 100644 --- a/src/Avalonia.Controls/Repeater/VirtualizationInfo.cs +++ b/src/Avalonia.Controls/Repeater/VirtualizationInfo.cs @@ -36,6 +36,7 @@ namespace Avalonia.Controls public bool IsHeldByLayout => Owner == ElementOwner.Layout; public bool IsRealized => IsHeldByLayout || Owner == ElementOwner.PinnedPool; public bool IsInUniqueIdResetPool => Owner == ElementOwner.UniqueIdResetPool; + public bool MustClearDataContext { get; set; } public bool KeepAlive { get; set; } public ElementOwner Owner { get; private set; } = ElementOwner.ElementFactory; public string UniqueId { get; private set; }