From d0974ca7a69380b30f5e38b4cb7f30e5f2f4aaa3 Mon Sep 17 00:00:00 2001 From: Nikita Tsukanov Date: Mon, 29 Sep 2025 18:53:42 +0500 Subject: [PATCH] [XAMLX] Propagate TypeConverters from the original CLR property to avalonia property (#19727) --- .../XamlIlAvaloniaPropertyHelper.cs | 1 + .../Xaml/XamlIlTests.cs | 51 +++++++++++++++++++ 2 files changed, 52 insertions(+) diff --git a/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/XamlIlAvaloniaPropertyHelper.cs b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/XamlIlAvaloniaPropertyHelper.cs index 48d7f26a5e..4e5a7bdd12 100644 --- a/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/XamlIlAvaloniaPropertyHelper.cs +++ b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/XamlIlAvaloniaPropertyHelper.cs @@ -224,6 +224,7 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions } Setters.Insert(0, new UnsetValueSetter(types, original.DeclaringType, field)); + TypeConverters = original.TypeConverters; } abstract class AvaloniaPropertyCustomSetter : IXamlILOptimizedEmitablePropertySetter, IEquatable diff --git a/tests/Avalonia.Markup.Xaml.UnitTests/Xaml/XamlIlTests.cs b/tests/Avalonia.Markup.Xaml.UnitTests/Xaml/XamlIlTests.cs index d7deddbd70..afb09c2838 100644 --- a/tests/Avalonia.Markup.Xaml.UnitTests/Xaml/XamlIlTests.cs +++ b/tests/Avalonia.Markup.Xaml.UnitTests/Xaml/XamlIlTests.cs @@ -458,6 +458,23 @@ namespace Avalonia.Markup.Xaml.UnitTests Assert.Equal(RuntimeXamlDiagnosticSeverity.Warning, warning.Severity); Assert.Equal("AVLN2208", warning.Id); } + + [Fact] + public void Type_Converters_Should_Work_When_Specified_With_Attributes_On_Avalonia_Properties() + { + using (UnitTestApplication.Start(TestServices.StyledWindow)) + { + + var parsed = (XamlIlClassWithTypeConverterOnAvaloniaProperty) + AvaloniaRuntimeXamlLoader.Parse(@" +", + typeof(XamlIlBugTestsEventHandlerCodeBehind).Assembly); + + Assert.Equal((IEnumerable)["a", "b", "c"], parsed.MyProp.Select(x => x.Value)); + } + } } public class XamlIlBugTestsEventHandlerCodeBehind : Window @@ -554,4 +571,38 @@ namespace Avalonia.Markup.Xaml.UnitTests { public int Count { get; set; }= 5; } + + public class XamlIlClassWithTypeConverterOnAvaloniaProperty : AvaloniaObject + { + public class MyType(string value) + { + public string Value => value; + } + + public class MyTypeConverter : TypeConverter + { + public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) + { + return sourceType == typeof(string); + } + + public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) + { + if (value is string s) + return s.Split([','], StringSplitOptions.RemoveEmptyEntries).Select(x => new MyType(x.Trim())); + return base.ConvertFrom(context, culture, value); + } + } + + public static readonly StyledProperty> MyPropProperty = AvaloniaProperty.Register>( + "MyProp"); + + [TypeConverter(typeof(MyTypeConverter))] + public IEnumerable MyProp + { + get => GetValue(MyPropProperty); + set => SetValue(MyPropProperty, value); + } + + } }