Browse Source

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
Steven Kirk 1 năm trước cách đây
mục cha
commit
c2e9679fae

+ 8 - 0
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<BindingExpressionGrammar.INode> { convertedNode };
+                    binding.Arguments.Add(new ParsedBindingPathNode(binding, context.GetAvaloniaTypes().CompiledBindingPath, nodes));
+                }
             }
 
             return node;

+ 66 - 0
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 = @"
+<Window xmlns='https://github.com/avaloniaui'
+        xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'
+        xmlns:local='clr-namespace:Avalonia.Markup.Xaml.UnitTests.MarkupExtensions;assembly=Avalonia.Markup.Xaml.UnitTests'
+        x:DataType='local:TestDataContext'>
+    <StackPanel>
+        <TextBlock Text='{CompiledBinding StringProperty}' x:Name='text' />
+        <TextBlock Text='{CompiledBinding ElementName=text}' x:Name='text2' />
+    </StackPanel>
+</Window>";
+                var window = (Window)AvaloniaRuntimeXamlLoader.Load(xaml);
+                var textBlock = window.GetControl<TextBlock>("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 = @"
+<Window xmlns='https://github.com/avaloniaui'
+        xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'
+        xmlns:local='clr-namespace:Avalonia.Markup.Xaml.UnitTests.MarkupExtensions;assembly=Avalonia.Markup.Xaml.UnitTests'
+        x:DataType='local:TestDataContext'>
+    <TextBlock Name='textBlock' Text='{CompiledBinding $self}' />
+</Window>";
+                var window = (Window)AvaloniaRuntimeXamlLoader.Load(xaml);
+                var textBlock = window.GetControl<TextBlock>("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 = @"
+<Window xmlns='https://github.com/avaloniaui'
+        xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'
+        xmlns:local='clr-namespace:Avalonia.Markup.Xaml.UnitTests.MarkupExtensions;assembly=Avalonia.Markup.Xaml.UnitTests'
+        x:DataType='local:TestDataContext'>
+    <TextBlock Name='textBlock' Text='{CompiledBinding RelativeSource={RelativeSource Self}}' />
+</Window>";
+                var window = (Window)AvaloniaRuntimeXamlLoader.Load(xaml);
+                var textBlock = window.GetControl<TextBlock>("textBlock");
+
+                window.ApplyTemplate();
+                window.Presenter!.ApplyTemplate();
+
+                Assert.Equal("Avalonia.Controls.TextBlock", textBlock.Text);
+            }
+        }
+
         [Fact]
         public void SupportsMethodBindingAsDelegate()
         {