Skip to content

Commit

Permalink
Fix XML child-value syntax in Setters (#16153)
Browse files Browse the repository at this point in the history
  • Loading branch information
maxkatz6 authored Jul 28, 2024
1 parent 413ff78 commit 2935763
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -82,17 +82,32 @@ public IXamlAstNode Transform(AstTransformationContext context, IXamlAstNode nod
}

var valueProperty = on.Children
.OfType<XamlAstXamlPropertyValueNode>().FirstOrDefault(p => p.Property.GetClrProperty().Name == "Value");
if (valueProperty?.Values?.Count == 1 && valueProperty.Values[0] is XamlAstTextNode)
.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();
if (textValue is not null
&& XamlTransformHelpers.TryGetCorrectlyTypedValue(context, textValue,
propType, out _))
{
if (!XamlTransformHelpers.TryGetCorrectlyTypedValue(context, valueProperty.Values[0],
propType, out var converted))
throw new XamlStyleTransformException(
$"Unable to convert property value to {propType.GetFqn()}",
valueProperty.Values[0]);

valueProperty.Property = new SetterValueProperty(valueProperty.Property,

var setterValueProperty = new SetterValueProperty(
(IXamlLineInfo)valueProperty?.Property ?? textValue,
on.Type.GetClrType(), propType, avaloniaTypes);
if (valueProperty is not null)
{
valueProperty.Property = setterValueProperty;
}
else
{
on.Children[on.Children.IndexOf(textValue)] =
new XamlAstXamlPropertyValueNode(textValue, setterValueProperty, textValue, false);
}
}
// If we have `Value` property with plain text content that wasn't parsed, throw an exception.
else if (valueProperty is not null && textValue is not null)
{
throw new XamlStyleTransformException($"Unable to convert property value to {propType.GetFqn()}", textValue);
}

// Handling a very specific case, when ITemplate value is used inside of Setter.Value,
Expand Down
18 changes: 18 additions & 0 deletions tests/Avalonia.Markup.Xaml.UnitTests/StyleTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,24 @@ public void Binding_Should_Be_Assigned_To_Setter_Value_Instead_Of_Bound()
}
}

[Fact]
public void Xml_Value_Should_Be_Assigned_To_Setter_Value()
{
using (UnitTestApplication.Start(TestServices.MockPlatformWrapper))
{
var style = (Style)AvaloniaRuntimeXamlLoader.Load(@"
<Style Selector='Button' xmlns='https://github.com/avaloniaui'>
<Setter Property='Margin'>
10, 4, 0, 4
</Setter>
</Style>");
var setter = (Setter)(style.Setters.First());

var thickness = Assert.IsType<Thickness>(setter.Value);
Assert.Equal(new Thickness(10, 4, 0, 4), thickness);
}
}

[Fact]
public void Setter_With_TwoWay_Binding_Should_Update_Source()
{
Expand Down

0 comments on commit 2935763

Please sign in to comment.