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
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with
42 additions and
6 deletions
-
src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlSetterTransformer.cs
-
tests/Avalonia.Markup.Xaml.UnitTests/StyleTests.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 _)) |
|
|
|
|
|
|
|
@ -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() |
|
|
|
{ |
|
|
|
|