From c2e9679faeae30dda888c47a994d2b0180cb7004 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 b62066e916..022a45469b 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 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers 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 abc9d400fd..7c7b8bcb00 100644 --- a/tests/Avalonia.Markup.Xaml.UnitTests/MarkupExtensions/CompiledBindingExtensionTests.cs +++ b/tests/Avalonia.Markup.Xaml.UnitTests/MarkupExtensions/CompiledBindingExtensionTests.cs @@ -849,6 +849,28 @@ namespace Avalonia.Markup.Xaml.UnitTests.MarkupExtensions } } + [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() { @@ -1573,6 +1595,28 @@ namespace Avalonia.Markup.Xaml.UnitTests.MarkupExtensions } } + [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() { @@ -1625,6 +1669,28 @@ namespace Avalonia.Markup.Xaml.UnitTests.MarkupExtensions } } + [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() {