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 1 year 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
.OfType<XamlAstXamlPropertyValueNode>()
.FirstOrDefault(p => p.Property.GetClrProperty().Name == "Value" && p.Values.Count == 1 && p.Values[0] is XamlAstTextNode);
var textValue = valueProperty?.Values.FirstOrDefault() as XamlAstTextNode
?? on.Children.OfType<XamlAstTextNode>().FirstOrDefault();
.FirstOrDefault(p => p.Property.GetClrProperty().Name == "Value");
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
&& XamlTransformHelpers.TryGetCorrectlyTypedValue(context, textValue,
propType, out _))

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

@ -1,8 +1,7 @@
using System.Linq;
using System.Reactive.Linq;
using Avalonia.Controls;
using Avalonia.Data;
using Avalonia.PropertyStore;
using Avalonia.Layout;
using Avalonia.Styling;
using Avalonia.UnitTests;
using Xunit;
@ -12,7 +11,7 @@ namespace Avalonia.Markup.Xaml.UnitTests
public class StyleTests : XamlTestBase
{
[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))
{
@ -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]
public void Xml_Value_Should_Be_Assigned_To_Setter_Value()
{

Loading…
Cancel
Save