From 34f8f3d5564d3d7b1584746c8dcaa887a5e235f5 Mon Sep 17 00:00:00 2001 From: Max Katz Date: Fri, 8 Jul 2022 01:57:06 -0400 Subject: [PATCH] Fix DataType set on Binding extension + add tests --- .../AvaloniaXamlIlBindingPathTransformer.cs | 5 + .../CompiledBindings/CompiledBindingPath.cs | 2 + .../CompiledBindingExtensionTests.cs | 95 +++++++++++++++++++ 3 files changed, 102 insertions(+) diff --git a/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlBindingPathTransformer.cs b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlBindingPathTransformer.cs index 3cc3504e16..e509d47932 100644 --- a/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlBindingPathTransformer.cs +++ b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlBindingPathTransformer.cs @@ -105,6 +105,11 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers { startType = TypeReferenceResolver.ResolveType(context, text.Text, isMarkupExtension: false, text, strict: true).Type; } + + if (dataTypeProperty?.Values.Count is 1 && dataTypeProperty.Values[0] is XamlTypeExtensionNode typeNode) + { + startType = typeNode.Value.GetClrType(); + } Func startTypeResolver = startType is not null ? () => startType : () => { diff --git a/src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/CompiledBindings/CompiledBindingPath.cs b/src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/CompiledBindings/CompiledBindingPath.cs index 73a14fd437..f78d4867ff 100644 --- a/src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/CompiledBindings/CompiledBindingPath.cs +++ b/src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/CompiledBindings/CompiledBindingPath.cs @@ -74,6 +74,8 @@ namespace Avalonia.Markup.Xaml.MarkupExtensions.CompiledBindings return pathRoot ?? new EmptyExpressionNode(); } + internal IEnumerable Elements => _elements; + internal SourceMode SourceMode => _elements.Count > 0 && _elements[0] is IControlSourceBindingPathElement ? SourceMode.Control : SourceMode.Data; internal object RawSource { get; } diff --git a/tests/Avalonia.Markup.Xaml.UnitTests/MarkupExtensions/CompiledBindingExtensionTests.cs b/tests/Avalonia.Markup.Xaml.UnitTests/MarkupExtensions/CompiledBindingExtensionTests.cs index 5ca25a176c..215ae4d54f 100644 --- a/tests/Avalonia.Markup.Xaml.UnitTests/MarkupExtensions/CompiledBindingExtensionTests.cs +++ b/tests/Avalonia.Markup.Xaml.UnitTests/MarkupExtensions/CompiledBindingExtensionTests.cs @@ -9,10 +9,13 @@ using System.Threading.Tasks; using Avalonia.Controls; using Avalonia.Controls.Presenters; using Avalonia.Controls.Templates; +using Avalonia.Data; using Avalonia.Data.Converters; using Avalonia.Data.Core; using Avalonia.Input; using Avalonia.Markup.Data; +using Avalonia.Markup.Xaml.MarkupExtensions; +using Avalonia.Markup.Xaml.MarkupExtensions.CompiledBindings; using Avalonia.Markup.Xaml.Templates; using Avalonia.Media; using Avalonia.Metadata; @@ -135,6 +138,56 @@ namespace Avalonia.Markup.Xaml.UnitTests.MarkupExtensions Assert.Equal(dataContext.ListProperty, textBlock.Items); } } + + [Fact] + public void ResolvesDataTypeFromBindingProperty() + { + using (UnitTestApplication.Start(TestServices.StyledWindow)) + { + var xaml = @" + + +"; + var window = (Window)AvaloniaRuntimeXamlLoader.Load(xaml); + var textBlock = window.FindControl("textBlock"); + + var dataContext = new TestDataContext + { + StringProperty = "foobar" + }; + + window.DataContext = dataContext; + + Assert.Equal(dataContext.StringProperty, textBlock.Text); + } + } + + [Fact] + public void ResolvesDataTypeFromBindingProperty_TypeExtension() + { + using (UnitTestApplication.Start(TestServices.StyledWindow)) + { + var xaml = @" + + +"; + var window = (Window)AvaloniaRuntimeXamlLoader.Load(xaml); + var textBlock = window.FindControl("textBlock"); + + var dataContext = new TestDataContext + { + StringProperty = "foobar" + }; + + window.DataContext = dataContext; + + Assert.Equal(dataContext.StringProperty, textBlock.Text); + } + } [Fact] public void ResolvesStreamTaskBindingCorrectly() @@ -1479,6 +1532,43 @@ namespace Avalonia.Markup.Xaml.UnitTests.MarkupExtensions } } + [Fact] + public void ResolvesDataTypeForAssignBinding() + { + using (UnitTestApplication.Start(TestServices.StyledWindow)) + { + var xaml = @" +"; + var control = (AssignBindingControl)AvaloniaRuntimeXamlLoader.Load(xaml); + var compiledPath = ((CompiledBindingExtension)control.X).Path; + + var node = Assert.IsType(Assert.Single(compiledPath.Elements)); + Assert.Equal(typeof(string), node.Property.PropertyType); + } + } + + [Fact] + public void ResolvesDataTypeForAssignBinding_FromBindingProperty() + { + using (UnitTestApplication.Start(TestServices.StyledWindow)) + { + var xaml = @" +"; + var control = (AssignBindingControl)AvaloniaRuntimeXamlLoader.Load(xaml); + var compiledPath = ((CompiledBindingExtension)control.X).Path; + + var node = Assert.IsType(Assert.Single(compiledPath.Elements)); + Assert.Equal(typeof(string), node.Property.PropertyType); + } + } + void Throws(string type, Action cb) { try @@ -1656,4 +1746,9 @@ namespace Avalonia.Markup.Xaml.UnitTests.MarkupExtensions } public class CustomDataTemplateInherit : CustomDataTemplate { } + + public class AssignBindingControl : Control + { + [AssignBinding] public IBinding X { get; set; } + } }