diff --git a/src/Controls/src/Build.Tasks/XamlCAssemblyResolver.cs b/src/Controls/src/Build.Tasks/XamlCAssemblyResolver.cs index 770af0376e08..0a9f15f7fb54 100644 --- a/src/Controls/src/Build.Tasks/XamlCAssemblyResolver.cs +++ b/src/Controls/src/Build.Tasks/XamlCAssemblyResolver.cs @@ -19,6 +19,7 @@ public override AssemblyDefinition Resolve(AssemblyNameReference name) return assembly; if (IsMscorlib(name) && (TryResolve(AssemblyNameReference.Parse("mscorlib"), out assembly) + || TryResolve(AssemblyNameReference.Parse("System.Private.CoreLib"), out assembly) || TryResolve(AssemblyNameReference.Parse("netstandard"), out assembly) || TryResolve(AssemblyNameReference.Parse("System.Runtime"), out assembly))) return assembly; @@ -42,6 +43,7 @@ bool TryResolve(AssemblyNameReference assemblyNameReference, out AssemblyDefinit static bool IsMscorlib(AssemblyNameReference name) { return name.Name == "mscorlib" + || name.Name == "System.Private.CoreLib" || name.Name == "System.Runtime" || name.Name == "netstandard"; } diff --git a/src/Controls/src/Xaml/XmlTypeXamlExtensions.cs b/src/Controls/src/Xaml/XmlTypeXamlExtensions.cs index 9c823998fee0..e394ccf02282 100644 --- a/src/Controls/src/Xaml/XmlTypeXamlExtensions.cs +++ b/src/Controls/src/Xaml/XmlTypeXamlExtensions.cs @@ -77,9 +77,19 @@ static class XmlTypeXamlExtensions var potentialTypes = new List<(string typeName, string clrNamespace, string assemblyName)>(); foreach (string typeName in lookupNames) + { foreach (XmlnsDefinitionAttribute xmlnsDefinitionAttribute in lookupAssemblies) + { potentialTypes.Add(new(typeName, xmlnsDefinitionAttribute.ClrNamespace, xmlnsDefinitionAttribute.AssemblyName)); + // As a fallback, for assembly=mscorlib try assembly=System.Private.CoreLib + if (xmlnsDefinitionAttribute.AssemblyName == "mscorlib" || xmlnsDefinitionAttribute.AssemblyName.StartsWith("mscorlib,", StringComparison.Ordinal)) + { + potentialTypes.Add(new(typeName, xmlnsDefinitionAttribute.ClrNamespace, "System.Private.CoreLib")); + } + } + } + T? type = null; foreach (var typeInfo in potentialTypes) if ((type = refFromTypeInfo(typeInfo)) != null) diff --git a/src/Controls/tests/DeviceTests/Xaml/RadioButtonUsing.xaml b/src/Controls/tests/DeviceTests/Xaml/RadioButtonUsing.xaml new file mode 100644 index 000000000000..c1c9311e7f3f --- /dev/null +++ b/src/Controls/tests/DeviceTests/Xaml/RadioButtonUsing.xaml @@ -0,0 +1,23 @@ + + + + + + Foo + Bar + Baz + + 42 + + + + + + 1 + + + + diff --git a/src/Controls/tests/DeviceTests/Xaml/RadioButtonUsing.xaml.cs b/src/Controls/tests/DeviceTests/Xaml/RadioButtonUsing.xaml.cs new file mode 100644 index 000000000000..5b4420d900aa --- /dev/null +++ b/src/Controls/tests/DeviceTests/Xaml/RadioButtonUsing.xaml.cs @@ -0,0 +1,14 @@ +using Microsoft.Maui.Controls; +using Microsoft.Maui.Controls.Xaml; + +namespace Microsoft.Maui.DeviceTests +{ + [XamlCompilation(XamlCompilationOptions.Compile)] + public partial class RadioButtonUsing : ContentPage + { + public RadioButtonUsing() + { + InitializeComponent(); + } + } +} diff --git a/src/Controls/tests/DeviceTests/Xaml/XamlTests.cs b/src/Controls/tests/DeviceTests/Xaml/XamlTests.cs new file mode 100644 index 000000000000..a4e7e823e5e7 --- /dev/null +++ b/src/Controls/tests/DeviceTests/Xaml/XamlTests.cs @@ -0,0 +1,98 @@ +using Microsoft.Maui.Controls; +using Microsoft.Maui.Controls.Xaml; +using Xunit; + +namespace Microsoft.Maui.DeviceTests +{ + public class XamlTests + { + [Fact("Parsed XAML can use mscorlib")] + public void Namespace_mscorlib_Parsed() + { + var page = new ContentPage(); + page.LoadFromXaml( + """ + + + + + 1 + + + + """); + Assert.IsType(page.Content); + Assert.Equal(1, ((RadioButton)page.Content).Value); + } + + [Fact("Compiled XAML can use mscorlib")] + public void Namespace_mscorlib_Compiled() + { + var page = new RadioButtonUsing(); + Assert.IsType(page.Content); + Assert.Equal(1, ((RadioButton)page.Content).Value); + } + + [Fact("Parsed XAML can use x:Array")] + public void x_Array_Parsed() + { + var page = new ContentPage(); + page.LoadFromXaml( + """ + + + + + + Foo + Bar + Baz + + + + + """); + string[] array = page.Resources["MyArray"] as string[]; + Assert.Equal(new[] { "Foo", "Bar", "Baz" }, array); + } + + [Fact("Compiled XAML can use x:Array")] + public void x_Array_Compiled() + { + var page = new RadioButtonUsing(); + string[] array = page.Resources["MyArray"] as string[]; + Assert.Equal(new[] { "Foo", "Bar", "Baz" }, array); + } + + [Fact("Parsed XAML can use x:Double")] + public void x_Double_Parsed() + { + var page = new ContentPage(); + page.LoadFromXaml( + """ + + + + + 42 + + + + """); + Assert.Equal(42d, page.Resources["MyNumber"]); + } + + [Fact("Compiled XAML can use x:Double")] + public void x_Double_Compiled() + { + var page = new RadioButtonUsing(); + Assert.Equal(42d, page.Resources["MyNumber"]); + } + } +} diff --git a/src/Controls/tests/Xaml.UnitTests/TestXmlnsUsing.xaml b/src/Controls/tests/Xaml.UnitTests/TestXmlnsUsing.xaml index 30d4dcb609e2..e6f0183f1d0d 100644 --- a/src/Controls/tests/Xaml.UnitTests/TestXmlnsUsing.xaml +++ b/src/Controls/tests/Xaml.UnitTests/TestXmlnsUsing.xaml @@ -2,8 +2,21 @@ - + + + + + 1 + + + + + 2 + + + diff --git a/src/Controls/tests/Xaml.UnitTests/TestXmlnsUsing.xaml.cs b/src/Controls/tests/Xaml.UnitTests/TestXmlnsUsing.xaml.cs index 4f1c9b976846..8157b097be5a 100644 --- a/src/Controls/tests/Xaml.UnitTests/TestXmlnsUsing.xaml.cs +++ b/src/Controls/tests/Xaml.UnitTests/TestXmlnsUsing.xaml.cs @@ -33,7 +33,9 @@ public void SupportUsingXmlns(bool useCompiledXaml) { var page = new TestXmlnsUsing(useCompiledXaml); Assert.That(page.Content, Is.Not.Null); - Assert.That(page.Content, Is.TypeOf()); + Assert.That(page.CustomView, Is.TypeOf()); + Assert.That(page.Radio1.Value, Is.EqualTo(1)); + Assert.That(page.Radio2.Value, Is.EqualTo(2)); } } }