Browse Source

Fix parsing of XAML setters when the child isn't a text node (#17044)

* Added failing XAML test for binding inside setters

* Fixed wrong XAML parsing of child value in setters
pull/17101/head
Julien Lebosquain 2 years ago
committed by GitHub
parent
commit
d5fdeb3d3a
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 22
      src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlSetterTransformer.cs
  2. 26
      tests/Avalonia.Markup.Xaml.UnitTests/StyleTests.cs

22
src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlSetterTransformer.cs

@ -80,9 +80,25 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers
var valueProperty = on.Children var valueProperty = on.Children
.OfType<XamlAstXamlPropertyValueNode>() .OfType<XamlAstXamlPropertyValueNode>()
.FirstOrDefault(p => p.Property.GetClrProperty().Name == "Value" && p.Values.Count == 1 && p.Values[0] is XamlAstTextNode); .FirstOrDefault(p => p.Property.GetClrProperty().Name == "Value");
var textValue = valueProperty?.Values.FirstOrDefault() as XamlAstTextNode
?? on.Children.OfType<XamlAstTextNode>().FirstOrDefault(); XamlAstTextNode? textValue = null;
if (valueProperty is not null)
{
if (valueProperty.Values.Count == 1)
textValue = valueProperty.Values[0] as XamlAstTextNode;
}
else
{
var nonPropertyChildren = on.Children
.Where(child => child is not XamlAstXamlPropertyValueNode)
.ToArray();
if (nonPropertyChildren.Length == 1)
textValue = nonPropertyChildren[0] as XamlAstTextNode;
}
if (textValue is not null if (textValue is not null
&& XamlTransformHelpers.TryGetCorrectlyTypedValue(context, textValue, && XamlTransformHelpers.TryGetCorrectlyTypedValue(context, textValue,
propType, out _)) propType, out _))

26
tests/Avalonia.Markup.Xaml.UnitTests/StyleTests.cs

@ -1,8 +1,7 @@
using System.Linq; using System.Linq;
using System.Reactive.Linq;
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Data; using Avalonia.Data;
using Avalonia.PropertyStore; using Avalonia.Layout;
using Avalonia.Styling; using Avalonia.Styling;
using Avalonia.UnitTests; using Avalonia.UnitTests;
using Xunit; using Xunit;
@ -12,7 +11,7 @@ namespace Avalonia.Markup.Xaml.UnitTests
public class StyleTests : XamlTestBase public class StyleTests : XamlTestBase
{ {
[Fact] [Fact]
public void Binding_Should_Be_Assigned_To_Setter_Value_Instead_Of_Bound() public void Binding_As_Attribute_Should_Be_Assigned_To_Setter_Value_Instead_Of_Bound()
{ {
using (UnitTestApplication.Start(TestServices.MockPlatformWrapper)) using (UnitTestApplication.Start(TestServices.MockPlatformWrapper))
{ {
@ -24,6 +23,27 @@ namespace Avalonia.Markup.Xaml.UnitTests
} }
} }
[Theory]
[InlineData(nameof(ContentControl.Content))] // standard property
[InlineData(nameof(Layoutable.Margin))] // primitive property which can be directly parsed
public void Binding_As_Element_Should_Be_Assigned_To_Setter_Value(string propertyName)
{
using (UnitTestApplication.Start(TestServices.MockPlatformWrapper))
{
var style = (Style)AvaloniaRuntimeXamlLoader.Load(
$"""
<Style Selector="Button" xmlns="https://github.com/avaloniaui">
<Setter Property="{propertyName}">
<Binding />
</Setter>
</Style>
""");
var setter = (Setter)style.Setters.First();
Assert.IsType<Binding>(setter.Value);
}
}
[Fact] [Fact]
public void Xml_Value_Should_Be_Assigned_To_Setter_Value() public void Xml_Value_Should_Be_Assigned_To_Setter_Value()
{ {

Loading…
Cancel
Save