diff --git a/src/SourceGenerators/Uno.UI.SourceGenerators.Tests/XamlCodeGeneratorTests/Out/TDBMIDTIRD/XamlCodeGenerator_MyResourceDictionary_92716e07ff456818f6d4125e055d4d57.cs b/src/SourceGenerators/Uno.UI.SourceGenerators.Tests/XamlCodeGeneratorTests/Out/TDBMIDTIRD/XamlCodeGenerator_MyResourceDictionary_92716e07ff456818f6d4125e055d4d57.cs index a6e3e15cbe04..ee3191108d83 100644 --- a/src/SourceGenerators/Uno.UI.SourceGenerators.Tests/XamlCodeGeneratorTests/Out/TDBMIDTIRD/XamlCodeGenerator_MyResourceDictionary_92716e07ff456818f6d4125e055d4d57.cs +++ b/src/SourceGenerators/Uno.UI.SourceGenerators.Tests/XamlCodeGeneratorTests/Out/TDBMIDTIRD/XamlCodeGenerator_MyResourceDictionary_92716e07ff456818f6d4125e055d4d57.cs @@ -95,6 +95,7 @@ public _View Build(object __ResourceOwner_1) __fe.Loading += delegate { _component_0.UpdateResourceBindings(); + _component_0.ApplyXBind(); } ; } @@ -261,6 +262,7 @@ public _View Build(object __ResourceOwner_1) __fe.Loading += delegate { _component_0.UpdateResourceBindings(); + _component_0.ApplyXBind(); } ; } @@ -350,6 +352,7 @@ public _View Build(object __ResourceOwner_1) __fe.Loading += delegate { _component_0.UpdateResourceBindings(); + _component_0.ApplyXBind(); } ; } diff --git a/src/SourceGenerators/Uno.UI.SourceGenerators/XamlGenerator/XamlFileGenerator.cs b/src/SourceGenerators/Uno.UI.SourceGenerators/XamlGenerator/XamlFileGenerator.cs index 3ead4da769ea..5f23b7778c7a 100644 --- a/src/SourceGenerators/Uno.UI.SourceGenerators/XamlGenerator/XamlFileGenerator.cs +++ b/src/SourceGenerators/Uno.UI.SourceGenerators/XamlGenerator/XamlFileGenerator.cs @@ -1084,6 +1084,7 @@ private void BuildCompiledBindingsInitializerForTemplate(IIndentedStringBuilder using (writer.BlockInvariant($"__fe.Loading += delegate")) { BuildComponentResouceBindingUpdates(writer); + BuildXBindApply(writer); BuildxBindEventHandlerInitializers(writer, CurrentScope.xBindEventsHandlers); } writer.AppendLineIndented(";"); @@ -1117,6 +1118,19 @@ private void BuildComponentResouceBindingUpdates(IIndentedStringBuilder writer) } } + private void BuildXBindApply(IIndentedStringBuilder writer) + { + for (var i = 0; i < CurrentScope.Components.Count; i++) + { + var component = CurrentScope.Components[i]; + + if (HasXBindMarkupExtension(component.XamlObject) && IsDependencyObject(component.XamlObject)) + { + writer.AppendLineIndented($"{component.MemberName}.ApplyXBind();"); + } + } + } + private void BuildComponentFields(IIndentedStringBuilder writer) { for (var i = 0; i < CurrentScope.Components.Count; i++) @@ -4230,8 +4244,10 @@ private string BuildXBindEvalFunction(XamlMemberDefinition member, XamlObjectDef var modeMember = bindNode.Members.FirstOrDefault(m => m.Member.Name == "Mode")?.Value?.ToString() ?? GetDefaultBindMode(); var rawBindBack = bindNode.Members.FirstOrDefault(m => m.Member.Name == "BindBack")?.Value?.ToString(); + var sourceInstance = CurrentResourceOwner is not null ? CurrentResourceOwnerName : "__that"; + var applyBindingParameters = _isHotReloadEnabled - ? "__that, (___b, __that)" + ? $"{sourceInstance}, (___b, {sourceInstance})" : "___b"; if (isInsideDataTemplate) @@ -4396,7 +4412,7 @@ string buildBindBack() ? ", new [] {" + string.Join(", ", formattedPaths) + "}" : ""; - return $".BindingApply({applyBindingParameters} => /*defaultBindMode{GetDefaultBindMode()} {rawFunction}*/ global::Uno.UI.Xaml.BindingHelper.SetBindingXBindProvider(___b, __that, ___ctx => {bindFunction}, {buildBindBack()} {pathsArray}))"; + return $".BindingApply({applyBindingParameters} => /*defaultBindMode{GetDefaultBindMode()} {rawFunction}*/ global::Uno.UI.Xaml.BindingHelper.SetBindingXBindProvider(___b, {sourceInstance}, ___ctx => {bindFunction}, {buildBindBack()} {pathsArray}))"; } } diff --git a/src/Uno.UI.RuntimeTests/Tests/BindingTests/BindingTests.cs b/src/Uno.UI.RuntimeTests/Tests/BindingTests/BindingTests.cs index 77b1a3fc8ba0..766866959400 100644 --- a/src/Uno.UI.RuntimeTests/Tests/BindingTests/BindingTests.cs +++ b/src/Uno.UI.RuntimeTests/Tests/BindingTests/BindingTests.cs @@ -128,4 +128,24 @@ public async Task When_FallbackValueThemeResource_WithDataContext() Assert.AreEqual(Microsoft.UI.Colors.Red, ((SolidColorBrush)myBtn.Foreground).Color); } + + [TestMethod] + public async Task When_XBind_To_Const_Page() + { + var SUT = new XBindConstPage(); + await UITestHelper.Load(SUT); + + Assert.AreEqual(200, SUT.XBoundBorder.ActualWidth); + Assert.AreEqual(200, SUT.XBoundBorder.ActualHeight); + } + + [TestMethod] + public async Task When_XBind_To_Const_Control_Template() + { + var SUT = new XBindConstControl(); + await UITestHelper.Load(SUT); + + Assert.AreEqual(200, SUT.XBoundBorder.ActualWidth); + Assert.AreEqual(200, SUT.XBoundBorder.ActualHeight); + } } diff --git a/src/Uno.UI.RuntimeTests/Tests/BindingTests/XBindConstControl.xaml b/src/Uno.UI.RuntimeTests/Tests/BindingTests/XBindConstControl.xaml new file mode 100644 index 000000000000..676d88c1ab33 --- /dev/null +++ b/src/Uno.UI.RuntimeTests/Tests/BindingTests/XBindConstControl.xaml @@ -0,0 +1,48 @@ + + + + + + + + + + + diff --git a/src/Uno.UI.RuntimeTests/Tests/BindingTests/XBindConstControl.xaml.cs b/src/Uno.UI.RuntimeTests/Tests/BindingTests/XBindConstControl.xaml.cs new file mode 100644 index 000000000000..0ab167c8306b --- /dev/null +++ b/src/Uno.UI.RuntimeTests/Tests/BindingTests/XBindConstControl.xaml.cs @@ -0,0 +1,27 @@ +using Microsoft.UI.Xaml.Controls; + +namespace Uno.UI.RuntimeTests.Tests; + +public sealed partial class XBindConstControl : Control +{ + private const double MyWidth = 200; + private const double MyHeight = 200; + + public XBindConstControl() + { + DefaultStyleKey = typeof(XBindConstControl); + + this.InitializeComponent(); + } + + public Border XBoundBorder { get; set; } + + protected override void OnApplyTemplate() + { + base.OnApplyTemplate(); + + XBoundBorder = GetTemplateChild("BoundBorder") as Border; + + + } +} diff --git a/src/Uno.UI.RuntimeTests/Tests/BindingTests/XBindConstPage.xaml b/src/Uno.UI.RuntimeTests/Tests/BindingTests/XBindConstPage.xaml new file mode 100644 index 000000000000..c87d58e9364c --- /dev/null +++ b/src/Uno.UI.RuntimeTests/Tests/BindingTests/XBindConstPage.xaml @@ -0,0 +1,29 @@ + + + + + + + + + + + + diff --git a/src/Uno.UI.RuntimeTests/Tests/BindingTests/XBindConstPage.xaml.cs b/src/Uno.UI.RuntimeTests/Tests/BindingTests/XBindConstPage.xaml.cs new file mode 100644 index 000000000000..107fca0a7e32 --- /dev/null +++ b/src/Uno.UI.RuntimeTests/Tests/BindingTests/XBindConstPage.xaml.cs @@ -0,0 +1,16 @@ +using Microsoft.UI.Xaml.Controls; + +namespace Uno.UI.RuntimeTests.Tests; + +public sealed partial class XBindConstPage : Page +{ + private const double MyWidth = 200; + private const double MyHeight = 200; + + public XBindConstPage() + { + this.InitializeComponent(); + } + + public Border XBoundBorder => BoundBorder; +}