From 10e3fc4db4866921b31cd04c72b05b3b2e76826a Mon Sep 17 00:00:00 2001 From: Shane Neuville Date: Mon, 27 May 2024 10:38:23 -0500 Subject: [PATCH] Weak Parent (#22561) * Weak Parent * - add logging --- src/Controls/src/Core/Element/Element.cs | 64 +++++++++++++++++++++--- 1 file changed, 58 insertions(+), 6 deletions(-) diff --git a/src/Controls/src/Core/Element/Element.cs b/src/Controls/src/Core/Element/Element.cs index bf3dada20406..f25b0d25944b 100644 --- a/src/Controls/src/Core/Element/Element.cs +++ b/src/Controls/src/Core/Element/Element.cs @@ -68,7 +68,7 @@ public abstract partial class Element : BindableObject, IElementDefinition, INam Guid? _id; - Element _parentOverride; + WeakReference _parentOverride; string _styleId; @@ -282,10 +282,29 @@ internal bool RemoveLogicalChild(Element element, int index) internal Element ParentOverride { - get { return _parentOverride; } + get + { + if (_parentOverride is null) + { + return null; + } + if (_parentOverride.TryGetTarget(out var parent)) + { + return parent; + } + else + { + Application.Current? + .FindMauiContext()? + .CreateLogger()? + .LogWarning($"The ParentOverride on {this} has been Garbage Collected. This should never happen. Please log a bug: https://github.com/dotnet/maui"); + } + + return null; + } set { - if (_parentOverride == value) + if (ParentOverride == value) return; bool emitChange = Parent != value; @@ -300,7 +319,10 @@ internal Element ParentOverride OnParentChangingCore(Parent, RealParent); } - _parentOverride = value; + if (value == null) + _parentOverride = null; + else + _parentOverride = new WeakReference(value); if (emitChange) { @@ -310,9 +332,39 @@ internal Element ParentOverride } } + WeakReference _realParent; /// For internal use by .NET MAUI. [EditorBrowsable(EditorBrowsableState.Never)] - public Element RealParent { get; private set; } + public Element RealParent + { + get + { + if (_realParent is null) + { + return null; + } + if (_realParent.TryGetTarget(out var parent)) + { + return parent; + } + else + { + Application.Current? + .FindMauiContext()? + .CreateLogger()? + .LogWarning($"The RealParent on {this} has been Garbage Collected. This should never happen. Please log a bug: https://github.com/dotnet/maui"); + } + + return null; + } + private set + { + if (value is null) + _realParent = null; + else + _realParent = new WeakReference(value); + } + } Dictionary DynamicResources => _dynamicResources ?? (_dynamicResources = new Dictionary()); @@ -328,7 +380,7 @@ void IElementDefinition.AddResourcesChangedListener(ActionMost application authors will not need to set the parent element by hand. public Element Parent { - get { return _parentOverride ?? RealParent; } + get { return ParentOverride ?? RealParent; } set => SetParent(value); }