Skip to content

Commit 5258d49

Browse files
committed
feat: Support CreateFromStringAttribute in XamlReader
1 parent 3dd31b8 commit 5258d49

File tree

3 files changed

+59
-7
lines changed

3 files changed

+59
-7
lines changed

src/Uno.UI/UI/Xaml/Markup/Reader/XamlObjectBuilder.cs

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
using System.Globalization;
66
using System.Linq;
77
using System.Reflection;
8-
using System.Text;
98
using System.Text.RegularExpressions;
109
using Uno.Extensions;
1110
using Uno.UI;
@@ -15,9 +14,8 @@
1514
using Windows.UI.Xaml.Controls;
1615
using Windows.UI.Xaml.Data;
1716
using Windows.UI.Xaml.Documents;
18-
using Windows.UI;
19-
using Windows.Foundation;
2017
using Windows.UI.Text;
18+
using Windows.Foundation.Metadata;
2119

2220
#if XAMARIN_ANDROID
2321
using _View = Android.Views.View;
@@ -38,7 +36,7 @@ internal class XamlObjectBuilder
3836
private Queue<Action> _postActions = new Queue<Action>();
3937
private static readonly Regex _attachedPropertMatch = new Regex(@"(\(.*?\))");
4038

41-
private static Type[] _genericConvertibles = new []
39+
private static Type[] _genericConvertibles = new[]
4240
{
4341
typeof(Media.Brush),
4442
typeof(Media.SolidColorBrush),
@@ -1006,6 +1004,39 @@ private void AddCollectionItems(object collectionInstance, IEnumerable<XamlObjec
10061004

10071005
private object? BuildLiteralValue(Type propertyType, string? memberValue)
10081006
{
1007+
if (propertyType.GetCustomAttribute<CreateFromStringAttribute>() is { } createFromString)
1008+
{
1009+
var sourceType = propertyType;
1010+
var methodName = createFromString.MethodName;
1011+
if (createFromString.MethodName.Contains("."))
1012+
{
1013+
var splitIndex = createFromString.MethodName.LastIndexOf(".");
1014+
var typeName = createFromString.MethodName.Substring(0, splitIndex);
1015+
sourceType = AppDomain.CurrentDomain
1016+
.GetAssemblies()
1017+
.Select(a => a.GetType(typeName))
1018+
.Trim()
1019+
.FirstOrDefault();
1020+
methodName = createFromString.MethodName.Substring(splitIndex + 1);
1021+
}
1022+
1023+
if (sourceType?.GetMethod(methodName) is { } conversionMethod && conversionMethod.IsStatic && !conversionMethod.IsPrivate)
1024+
{
1025+
try
1026+
{
1027+
return conversionMethod.Invoke(null, new object[] { memberValue });
1028+
}
1029+
catch (Exception ex)
1030+
{
1031+
throw new XamlParseException("Executing [CreateFromString] method for type " + propertyType + " failed.", ex);
1032+
}
1033+
}
1034+
else
1035+
{
1036+
throw new XamlParseException("Method referenced by [CreateFromString] cannot be found for " + propertyType);
1037+
}
1038+
}
1039+
10091040
return Uno.UI.DataBinding.BindingPropertyHelper.Convert(() => propertyType, memberValue);
10101041
}
10111042

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
using System;
2+
3+
namespace Windows.Foundation.Metadata;
4+
5+
/// <summary>
6+
/// Creates a metadata object from a string.
7+
/// </summary>
8+
public partial class CreateFromStringAttribute : Attribute
9+
{
10+
/// <summary>
11+
/// Creates an instance of the attribute.
12+
/// </summary>
13+
public CreateFromStringAttribute() : base()
14+
{
15+
}
16+
17+
/// <summary>
18+
/// Full name of the method performing conversion from string.
19+
/// </summary>
20+
public string MethodName;
21+
}

src/Uno.UWP/Generated/3.0.0.0/Windows.Foundation.Metadata/CreateFromStringAttribute.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,20 @@
22
#pragma warning disable 114 // new keyword hiding
33
namespace Windows.Foundation.Metadata
44
{
5-
#if __ANDROID__ || __IOS__ || NET461 || __WASM__ || __SKIA__ || __NETSTD_REFERENCE__ || __MACOS__
5+
#if false
66
[global::Uno.NotImplemented]
77
#endif
88
public partial class CreateFromStringAttribute : global::System.Attribute
99
{
10-
#if __ANDROID__ || __IOS__ || NET461 || __WASM__ || __SKIA__ || __NETSTD_REFERENCE__ || __MACOS__
10+
#if false
1111
[global::Uno.NotImplemented("__ANDROID__", "__IOS__", "NET461", "__WASM__", "__SKIA__", "__NETSTD_REFERENCE__", "__MACOS__")]
1212
public CreateFromStringAttribute() : base()
1313
{
1414
global::Windows.Foundation.Metadata.ApiInformation.TryRaiseNotImplemented("Windows.Foundation.Metadata.CreateFromStringAttribute", "CreateFromStringAttribute.CreateFromStringAttribute()");
1515
}
1616
#endif
1717
// Forced skipping of method Windows.Foundation.Metadata.CreateFromStringAttribute.CreateFromStringAttribute()
18-
#if __ANDROID__ || __IOS__ || NET461 || __WASM__ || __SKIA__ || __NETSTD_REFERENCE__ || __MACOS__
18+
#if false
1919
public string MethodName;
2020
#endif
2121
}

0 commit comments

Comments
 (0)