diff --git a/src/SourceGenerators/Uno.UI.SourceGenerators/DependencyObject/DependencyObjectGenerator.cs b/src/SourceGenerators/Uno.UI.SourceGenerators/DependencyObject/DependencyObjectGenerator.cs index 7db7533fa2c3..b1b5579cb6ab 100644 --- a/src/SourceGenerators/Uno.UI.SourceGenerators/DependencyObject/DependencyObjectGenerator.cs +++ b/src/SourceGenerators/Uno.UI.SourceGenerators/DependencyObject/DependencyObjectGenerator.cs @@ -172,8 +172,14 @@ private void ProcessType(INamedTypeSymbol typeSymbol) AnalyzerSuppressionsGenerator.Generate(builder, _analyzerSuppressions); }; - var internalDependencyObject = _isUnoSolution && !typeSymbol.IsSealed ? ", IDependencyObjectInternal" : ""; - using (typeSymbol.AddToIndentedStringBuilder(builder, beforeClassHeaderAction, afterClassHeader: $" : IDependencyObjectStoreProvider, IWeakReferenceProvider{internalDependencyObject}")) + var implementations = new string?[] + { + "IDependencyObjectStoreProvider", + _isUnoSolution && !typeSymbol.IsSealed ? "IDependencyObjectInternal" : null, + "ITemplatedParentProvider", + "IWeakReferenceProvider", + }.Where(x => x is not null); + using (typeSymbol.AddToIndentedStringBuilder(builder, beforeClassHeaderAction, afterClassHeader: " : " + string.Join(", ", implementations))) { AnalyzerSuppressionsGenerator.Generate(builder, _analyzerSuppressions); @@ -774,33 +780,33 @@ private void GenerateDependencyObjectImplementation(INamedTypeSymbol typeSymbol, } } - //builder.AppendLineIndented("[EditorBrowsable(EditorBrowsableState.Never)]"); - //using (builder.BlockInvariant($"DependencyObject IDependencyObjectInternal.TemplatedParent")) - //{ - // builder.AppendLineIndented("get => GetTemplatedParent();"); - // builder.AppendLineIndented("set => SetTemplatedParent(value);"); - //} + var unoBrowsableOnly = _isUnoSolution ? null : "[EditorBrowsable(EditorBrowsableState.Never)]"; - builder.AppendLineIndented($"public {(typeSymbol.IsSealed ? "" : "virtual")} DependencyObject GetTemplatedParent() => null;"); + builder.AppendLine(); + builder.AppendMultiLineIndented($$""" + {{unoBrowsableOnly}}private ManagedWeakReference _templatedParentWeakRef; + {{unoBrowsableOnly}}public ManagedWeakReference GetTemplatedParentWeakRef() => _templatedParentWeakRef; - builder.AppendMultiLineIndented(""" - [EditorBrowsable(EditorBrowsableState.Never)] - public void SetTemplatedParent(DependencyObject parent) + {{unoBrowsableOnly}}public DependencyObject GetTemplatedParent() => _templatedParentWeakRef?.Target as DependencyObject; + {{unoBrowsableOnly}}public void SetTemplatedParent(DependencyObject parent) { - if (parent != null) - { - //global::System.Diagnostics.Debug.Assert(parent - // is global::Windows.UI.Xaml.Controls.Control - // or global::Windows.UI.Xaml.Controls.ContentPresenter - // or global::Windows.UI.Xaml.Controls.ItemsPresenter); - //global::System.Diagnostics.Debug.Assert(GetTemplatedParent() == null); - } - + //if (parent != null) + //{ + // global::System.Diagnostics.Debug.Assert(parent + // is global::Windows.UI.Xaml.Controls.Control + // or global::Windows.UI.Xaml.Controls.ContentPresenter + // or global::Windows.UI.Xaml.Controls.ItemsPresenter); + // global::System.Diagnostics.Debug.Assert(GetTemplatedParent() == null); + //} + SetTemplatedParentImpl(parent); } - """); - - builder.AppendLineIndented($"{(typeSymbol.IsSealed ? "private" : "private protected virtual")} void SetTemplatedParentImpl(DependencyObject parent) {{ }}"); + {{unoBrowsableOnly}}{{(typeSymbol.IsSealed ? "private" : "private protected virtual")}} void SetTemplatedParentImpl(DependencyObject parent) + { + _templatedParentWeakRef = (parent as IWeakReferenceProvider)?.WeakReference; + } + """ + ); } } } diff --git a/src/SourceGenerators/Uno.UI.SourceGenerators/XamlGenerator/XamlFileGenerator.cs b/src/SourceGenerators/Uno.UI.SourceGenerators/XamlGenerator/XamlFileGenerator.cs index 5ceca340d3bd..1f74eab9282f 100644 --- a/src/SourceGenerators/Uno.UI.SourceGenerators/XamlGenerator/XamlFileGenerator.cs +++ b/src/SourceGenerators/Uno.UI.SourceGenerators/XamlGenerator/XamlFileGenerator.cs @@ -3045,7 +3045,8 @@ private void BuildExtendedProperties(IIndentedStringBuilder outerwriter, XamlObj } var isInsideFrameworkTemplate = IsMemberInsideFrameworkTemplate(objectDefinition).isInside; - if (isInsideFrameworkTemplate && isFrameworkElement) + var isDependencyObject = IsType(objectDefinitionType, Generation.DependencyObjectSymbol.Value); + if (isInsideFrameworkTemplate && isDependencyObject) { writer.AppendLineIndented($"{closureName}.SetTemplatedParent(__settings?.TemplatedParent);"); writer.AppendLineIndented($"__settings?.TemplateMemberCreatedCallback?.Invoke({closureName});"); diff --git a/src/Uno.UI/DataBinding/BindingExpression.cs b/src/Uno.UI/DataBinding/BindingExpression.cs index 8a15128d0e7d..cee54c2e112a 100644 --- a/src/Uno.UI/DataBinding/BindingExpression.cs +++ b/src/Uno.UI/DataBinding/BindingExpression.cs @@ -54,7 +54,7 @@ public object DataContext { if (ParentBinding.IsTemplateBinding) { - return (_view?.Target as FrameworkElement)?.GetTemplatedParent(); + return (_view?.Target as ITemplatedParentProvider)?.GetTemplatedParent(); } if (_isElementNameSource || ExplicitSource != null) { @@ -149,7 +149,7 @@ Binding binding ApplyElementName(); } - private ManagedWeakReference GetWeakTemplatedParent() => (_view?.Target as FrameworkElement)?.GetTemplatedParentWeakRef(); + private ManagedWeakReference GetWeakTemplatedParent() => (_view?.Target as ITemplatedParentProvider)?.GetTemplatedParentWeakRef(); private ManagedWeakReference GetWeakDataContext() { diff --git a/src/Uno.UI/DataBinding/ITemplatedParentProvider.cs b/src/Uno.UI/DataBinding/ITemplatedParentProvider.cs new file mode 100644 index 000000000000..f88a3d1f346c --- /dev/null +++ b/src/Uno.UI/DataBinding/ITemplatedParentProvider.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Microsoft.UI.Xaml; + +namespace Uno.UI.DataBinding; + +[EditorBrowsable(EditorBrowsableState.Never)] +public interface ITemplatedParentProvider +{ + ManagedWeakReference GetTemplatedParentWeakRef(); + + DependencyObject GetTemplatedParent(); + + void SetTemplatedParent(DependencyObject parent); +} diff --git a/src/Uno.UI/UI/Xaml/FrameworkElement.cs b/src/Uno.UI/UI/Xaml/FrameworkElement.cs index 0bdc5757b41a..d01e084b630f 100644 --- a/src/Uno.UI/UI/Xaml/FrameworkElement.cs +++ b/src/Uno.UI/UI/Xaml/FrameworkElement.cs @@ -277,16 +277,6 @@ public bool IsParsing } } - internal bool IsTemplateRoot { get; set; } // fixme@xy: remove debug code - - private ManagedWeakReference _templatedParentWeakRef; - internal ManagedWeakReference GetTemplatedParentWeakRef() => _templatedParentWeakRef; - public override DependencyObject GetTemplatedParent() => _templatedParentWeakRef?.Target as DependencyObject; - private protected override void SetTemplatedParentImpl(DependencyObject parent) - { - _templatedParentWeakRef = (parent as IWeakReferenceProvider)?.WeakReference; - } - /// /// Provides the behavior for the "Measure" pass of the layout cycle. Classes can override this method to define their own "Measure" pass behavior. /// diff --git a/src/Uno.UI/UI/Xaml/FrameworkTemplate.cs b/src/Uno.UI/UI/Xaml/FrameworkTemplate.cs index 13a2f00a2e1f..4d93fc2b15d3 100644 --- a/src/Uno.UI/UI/Xaml/FrameworkTemplate.cs +++ b/src/Uno.UI/UI/Xaml/FrameworkTemplate.cs @@ -109,10 +109,10 @@ public FrameworkTemplate(object? owner, FrameworkTemplateBuilder? factory) FrameworkTemplatePool.Instance.TrackMaterializedTemplate(this, view, members); } - if (view is FrameworkElement fe) - { - fe.IsTemplateRoot = true; - } + //if (view is FrameworkElement fe) + //{ + // fe.IsTemplateRoot = true; + //} return view; } diff --git a/src/Uno.UI/UI/Xaml/IDependencyObjectInternal.cs b/src/Uno.UI/UI/Xaml/IDependencyObjectInternal.cs index 2f186277cedd..b1db6254a387 100644 --- a/src/Uno.UI/UI/Xaml/IDependencyObjectInternal.cs +++ b/src/Uno.UI/UI/Xaml/IDependencyObjectInternal.cs @@ -1,7 +1,7 @@ namespace Microsoft.UI.Xaml { /// - /// Internal implemenation for + /// Internal implementation for /// internal partial interface IDependencyObjectInternal {