From b8683229b9cecbf26ba3c1158edf8b0225a0fff0 Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Tue, 6 Feb 2024 21:41:11 +0100 Subject: [PATCH] Fix CompiledBinding with RelativeSource/ElementName but no Path (#14514) * Added failing tests for #14456. And one passing test. * Handle converted compiled binding nodes... ...without a path. Previously the `convertedNode` was being discarded if the binding node had no arguments or property value assignments. Fixes #14456 --- .../AvaloniaXamlIlBindingPathParser.cs | 8 +++ .../CompiledBindingExtensionTests.cs | 66 +++++++++++++++++++ 2 files changed, 74 insertions(+) diff --git a/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlBindingPathParser.cs b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlBindingPathParser.cs index 736e764aa7c..8173f124d3b 100644 --- a/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlBindingPathParser.cs +++ b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlBindingPathParser.cs @@ -66,8 +66,16 @@ public IXamlAstNode Transform(AstTransformationContext context, IXamlAstNode nod bindingPathAssignment.Values[0] = new ParsedBindingPathNode(pathValue, context.GetAvaloniaTypes().CompiledBindingPath, nodes); } + + foundPath = true; } } + + if (!foundPath && convertedNode != null) + { + var nodes = new List { convertedNode }; + binding.Arguments.Add(new ParsedBindingPathNode(binding, context.GetAvaloniaTypes().CompiledBindingPath, nodes)); + } } return node; diff --git a/tests/Avalonia.Markup.Xaml.UnitTests/MarkupExtensions/CompiledBindingExtensionTests.cs b/tests/Avalonia.Markup.Xaml.UnitTests/MarkupExtensions/CompiledBindingExtensionTests.cs index 9d82674fb61..be8b3950ee7 100644 --- a/tests/Avalonia.Markup.Xaml.UnitTests/MarkupExtensions/CompiledBindingExtensionTests.cs +++ b/tests/Avalonia.Markup.Xaml.UnitTests/MarkupExtensions/CompiledBindingExtensionTests.cs @@ -824,6 +824,28 @@ public void ResolvesElementNameBindingFromLongForm() } } + [Fact] + public void ResolvesElementNameBindingFromLongFormWithoutPath() + { + using (UnitTestApplication.Start(TestServices.StyledWindow)) + { + var xaml = @" + + + + + +"; + var window = (Window)AvaloniaRuntimeXamlLoader.Load(xaml); + var textBlock = window.GetControl("text2"); + + Assert.Equal("Avalonia.Controls.TextBlock", textBlock.Text); + } + } + [Fact] public void ResolvesRelativeSourceBindingLongForm() { @@ -1493,6 +1515,28 @@ public void SupportCastToTypeInExpressionWithProperty_ExplicitPropertyCast() } } + [Fact] + public void Binds_To_Self() + { + using (UnitTestApplication.Start(TestServices.StyledWindow)) + { + var xaml = @" + + +"; + var window = (Window)AvaloniaRuntimeXamlLoader.Load(xaml); + var textBlock = window.GetControl("textBlock"); + + window.ApplyTemplate(); + window.Presenter!.ApplyTemplate(); + + Assert.Equal("Avalonia.Controls.TextBlock", textBlock.Text); + } + } + [Fact] public void Binds_To_Self_Without_DataType() { @@ -1545,6 +1589,28 @@ public void Binds_To_Self_In_Style() } } + [Fact] + public void Binds_To_RelativeSource_Self() + { + using (UnitTestApplication.Start(TestServices.StyledWindow)) + { + var xaml = @" + + +"; + var window = (Window)AvaloniaRuntimeXamlLoader.Load(xaml); + var textBlock = window.GetControl("textBlock"); + + window.ApplyTemplate(); + window.Presenter!.ApplyTemplate(); + + Assert.Equal("Avalonia.Controls.TextBlock", textBlock.Text); + } + } + [Fact] public void SupportsMethodBindingAsDelegate() {