From f5df597bc16d2eaf60e359df2c7bde769f093afb Mon Sep 17 00:00:00 2001 From: Ramez Ragaa Date: Tue, 5 Mar 2024 01:06:51 +0200 Subject: [PATCH] fix: xLoad not updating bindings when a child sets x:Bind --- .../XamlGenerator/XamlFileGenerator.cs | 120 +++++++++--------- 1 file changed, 58 insertions(+), 62 deletions(-) diff --git a/src/SourceGenerators/Uno.UI.SourceGenerators/XamlGenerator/XamlFileGenerator.cs b/src/SourceGenerators/Uno.UI.SourceGenerators/XamlGenerator/XamlFileGenerator.cs index 90c971f128bc..2458d0f9eb58 100644 --- a/src/SourceGenerators/Uno.UI.SourceGenerators/XamlGenerator/XamlFileGenerator.cs +++ b/src/SourceGenerators/Uno.UI.SourceGenerators/XamlGenerator/XamlFileGenerator.cs @@ -6109,7 +6109,7 @@ private void BuildChild(IIndentedStringBuilder writer, XamlMemberDefinition? own } else { - using (TryGenerateDeferLoadStrategy(writer, knownType, xamlObjectDefinition)) + using (TryGenerateDeferedLoadStrategy(writer, knownType, xamlObjectDefinition)) { using (writer.BlockInvariant("new {0}{1}", GetGlobalizedTypeName(fullTypeName), GenerateConstructorParameters(knownType))) { @@ -6297,7 +6297,7 @@ private IEnumerable EnumerateSubElements(IEnumerable EnumerateSubElements(IEnumerable(); + if (hasLoadMarkup) { + members.Add(GenerateBinding("Load", loadMember, definition)); + } - var members = new List(); + var isInsideFrameworkTemplate = IsMemberInsideFrameworkTemplate(definition).isInside; - if (hasLoadMarkup) - { - members.Add(GenerateBinding("Load", loadMember, definition)); - } + var needsBindingUpdates = HasXBindMarkupExtension(definition) || HasMarkupExtensionNeedingComponent(definition); + var childrenNeedBindingUpdates = CurrentXLoadScope?.Components.Any(c => HasXBindMarkupExtension(c.ObjectDefinition) || HasMarkupExtensionNeedingComponent(c.ObjectDefinition)) ?? false; + if ((!_isTopLevelDictionary || isInsideFrameworkTemplate) && (needsBindingUpdates || childrenNeedBindingUpdates)) + { + var xamlObjectDef = new XamlObjectDefinition(elementStubType, 0, 0, definition, namespaces: null); + xamlObjectDef.Members.AddRange(members); - var isInsideFrameworkTemplate = IsMemberInsideFrameworkTemplate(definition).isInside; - if ((!_isTopLevelDictionary || isInsideFrameworkTemplate) - && (HasXBindMarkupExtension(definition) || HasMarkupExtensionNeedingComponent(definition))) - { - var xamlObjectDef = new XamlObjectDefinition(elementStubType, 0, 0, definition, namespaces: null); - xamlObjectDef.Members.AddRange(members); + AddComponentForParentScope(xamlObjectDef); - AddComponentForParentScope(xamlObjectDef); + var componentName = CurrentScope.Components.Last().MemberName; + writer.AppendLineIndented($"__that.{componentName} = {closureName};"); - var componentName = CurrentScope.Components.Last().MemberName; - writer.AppendLineIndented($"__that.{componentName} = {closureName};"); + if (!isInsideFrameworkTemplate) + { + EnsureXClassName(); - if (!isInsideFrameworkTemplate) - { - EnsureXClassName(); + writer.AppendLineIndented($"var {componentName}_update_That = ({CurrentResourceOwnerName} as global::Uno.UI.DataBinding.IWeakReferenceProvider).WeakReference;"); - writer.AppendLineIndented($"var {componentName}_update_That = ({CurrentResourceOwnerName} as global::Uno.UI.DataBinding.IWeakReferenceProvider).WeakReference;"); + if (nameMember != null) + { + writer.AppendLineIndented($"var {componentName}_update_subject_capture = _{nameMember.Value}Subject;"); + } - if (nameMember != null) + using (writer.BlockInvariant($"void {componentName}_update(global::Microsoft.UI.Xaml.ElementStub sender)")) + { + using (writer.BlockInvariant($"if ({componentName}_update_That.Target is {_xClassName} that)")) { - writer.AppendLineIndented($"var {componentName}_update_subject_capture = _{nameMember.Value}Subject;"); - } - using (writer.BlockInvariant($"void {componentName}_update(global::Microsoft.UI.Xaml.ElementStub sender)")) - { - using (writer.BlockInvariant($"if ({componentName}_update_That.Target is {_xClassName} that)")) + using (writer.BlockInvariant($"if (sender.IsMaterialized)")) { - - using (writer.BlockInvariant($"if (sender.IsMaterialized)")) - { - writer.AppendLineIndented($"that.Bindings.UpdateResources();"); - } + writer.AppendLineIndented($"that.Bindings.UpdateResources();"); } } + } + + writer.AppendLineIndented($"{closureName}.MaterializationChanged += {componentName}_update;"); - writer.AppendLineIndented($"{closureName}.MaterializationChanged += {componentName}_update;"); + writer.AppendLineIndented($"var owner = this;"); - writer.AppendLineIndented($"var owner = this;"); + if (_isHotReloadEnabled) + { + // Attach the current context to itself to avoid having a closure in the lambda + writer.AppendLineIndented($"global::Uno.UI.Helpers.MarkupHelper.SetElementProperty({closureName}, \"{componentName}_owner\", owner);"); + } + using (writer.BlockInvariant($"void {componentName}_materializing(object sender)")) + { if (_isHotReloadEnabled) { - // Attach the current context to itself to avoid having a closure in the lambda - writer.AppendLineIndented($"global::Uno.UI.Helpers.MarkupHelper.SetElementProperty({closureName}, \"{componentName}_owner\", owner);"); + writer.AppendLineIndented($"var owner = global::Uno.UI.Helpers.MarkupHelper.GetElementProperty<{CurrentScope.ClassName}>(sender, \"{componentName}_owner\");"); } - using (writer.BlockInvariant($"void {componentName}_materializing(object sender)")) - { - if (_isHotReloadEnabled) - { - writer.AppendLineIndented($"var owner = global::Uno.UI.Helpers.MarkupHelper.GetElementProperty<{CurrentScope.ClassName}>(sender, \"{componentName}_owner\");"); - } - - // Refresh the bindings when the ElementStub is unloaded. This assumes that - // ElementStub will be unloaded **after** the stubbed control has been created - // in order for the component field to be filled, and Bindings.Update() to do its work. + // Refresh the bindings when the ElementStub is unloaded. This assumes that + // ElementStub will be unloaded **after** the stubbed control has been created + // in order for the component field to be filled, and Bindings.Update() to do its work. - using (writer.BlockInvariant($"if ({componentName}_update_That.Target is {_xClassName} that)")) + using (writer.BlockInvariant($"if ({componentName}_update_That.Target is {_xClassName} that)")) + { + if (CurrentXLoadScope != null) { - if (CurrentXLoadScope != null) + foreach (var component in CurrentXLoadScope.Components) { - foreach (var component in CurrentXLoadScope.Components) - { - writer.AppendLineIndented($"that.{component.VariableName}.ApplyXBind();"); - writer.AppendLineIndented($"that.{component.VariableName}.UpdateResourceBindings();"); - } - - BuildxBindEventHandlerInitializers(writer, CurrentXLoadScope.xBindEventsHandlers, "that."); + writer.AppendLineIndented($"that.{component.VariableName}.ApplyXBind();"); + writer.AppendLineIndented($"that.{component.VariableName}.UpdateResourceBindings();"); } + + BuildxBindEventHandlerInitializers(writer, CurrentXLoadScope.xBindEventsHandlers, "that."); } } - - writer.AppendLineIndented($"{closureName}.Materializing += {componentName}_materializing;"); - } - else - { - // TODO for https://github.com/unoplatform/uno/issues/6700 } + writer.AppendLineIndented($"{closureName}.Materializing += {componentName}_materializing;"); + } + else + { + // TODO for https://github.com/unoplatform/uno/issues/6700 } } @@ -6475,8 +6472,7 @@ XamlMemberDefinition GenerateBinding(string name, XamlMemberDefinition? memberDe } xLoadScopeDisposable?.Dispose(); - } - ); + }); } return null;