Skip to content

Commit

Permalink
fix: xLoad not updating bindings when a child sets x:Bind
Browse files Browse the repository at this point in the history
  • Loading branch information
ramezgerges committed Mar 4, 2024
1 parent d00f394 commit f5df597
Showing 1 changed file with 58 additions and 62 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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)))
{
Expand Down Expand Up @@ -6297,7 +6297,7 @@ private IEnumerable<XamlObjectDefinition> EnumerateSubElements(IEnumerable<XamlO
yield break;
}

private IDisposable? TryGenerateDeferLoadStrategy(IIndentedStringBuilder writer, INamedTypeSymbol? targetType, XamlObjectDefinition definition)
private IDisposable? TryGenerateDeferedLoadStrategy(IIndentedStringBuilder writer, INamedTypeSymbol? targetType, XamlObjectDefinition definition)
{
TryAnnotateWithGeneratorSource(writer);
var strategy = FindMember(definition, "DeferLoadStrategy");
Expand Down Expand Up @@ -6362,94 +6362,91 @@ private IEnumerable<XamlObjectDefinition> EnumerateSubElements(IEnumerable<XamlO
);
}

var members = new List<XamlMemberDefinition>();

if (hasLoadMarkup)
{
members.Add(GenerateBinding("Load", loadMember, definition));
}

var members = new List<XamlMemberDefinition>();
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
}
}

Expand All @@ -6475,8 +6472,7 @@ XamlMemberDefinition GenerateBinding(string name, XamlMemberDefinition? memberDe
}

xLoadScopeDisposable?.Dispose();
}
);
});
}

return null;
Expand Down

0 comments on commit f5df597

Please sign in to comment.