diff --git a/src/Controls/src/Build.Tasks/CompiledMarkupExtensions/StaticExtension.cs b/src/Controls/src/Build.Tasks/CompiledMarkupExtensions/StaticExtension.cs index 76d23cffc4ac..598c5a723fdc 100644 --- a/src/Controls/src/Build.Tasks/CompiledMarkupExtensions/StaticExtension.cs +++ b/src/Controls/src/Build.Tasks/CompiledMarkupExtensions/StaticExtension.cs @@ -24,7 +24,7 @@ public IEnumerable ProvideValue(IElementNode node, ModuleDefinition var typename = member.Substring(0, dotIdx); var membername = member.Substring(dotIdx + 1); - var typeRef = module.ImportReference(XmlTypeExtensions.GetTypeReference(context.Cache, typename, module, node as BaseNode)); + var typeRef = module.ImportReference(XmlTypeExtensions.GetTypeReference(context.Cache, typename, false, module, node as BaseNode)); var fieldRef = GetFieldReference(context.Cache, typeRef, membername, module); var propertyDef = GetPropertyDefinition(context.Cache, typeRef, membername, module); diff --git a/src/Controls/src/Build.Tasks/CompiledMarkupExtensions/TypeExtension.cs b/src/Controls/src/Build.Tasks/CompiledMarkupExtensions/TypeExtension.cs index add45a05eea9..fb727c73e2b3 100644 --- a/src/Controls/src/Build.Tasks/CompiledMarkupExtensions/TypeExtension.cs +++ b/src/Controls/src/Build.Tasks/CompiledMarkupExtensions/TypeExtension.cs @@ -28,7 +28,7 @@ public IEnumerable ProvideValue(IElementNode node, ModuleDefinition node.CollectionItems.Clear(); } - var typeref = module.ImportReference(XmlTypeExtensions.GetTypeReference(context.Cache, valueNode.Value as string, module, node as BaseNode)); + var typeref = module.ImportReference(XmlTypeExtensions.GetTypeReference(context.Cache, valueNode.Value as string, false, module, node as BaseNode)); context.TypeExtensions[node] = typeref ?? throw new BuildException(BuildExceptionCode.TypeResolution, node as IXmlLineInfo, null, valueNode.Value); diff --git a/src/Controls/src/Build.Tasks/XmlTypeExtensions.cs b/src/Controls/src/Build.Tasks/XmlTypeExtensions.cs index 57dfee10f62c..6d3a1538d814 100644 --- a/src/Controls/src/Build.Tasks/XmlTypeExtensions.cs +++ b/src/Controls/src/Build.Tasks/XmlTypeExtensions.cs @@ -49,8 +49,10 @@ static IList GatherXmlnsDefinitionAttributes(ModuleDef return xmlnsDefinitions; } - public static TypeReference GetTypeReference(XamlCache cache, string xmlType, ModuleDefinition module, BaseNode node) + => GetTypeReference(cache, xmlType, true, module, node); + + public static TypeReference GetTypeReference(XamlCache cache, string xmlType, bool tryExtensionFirst, ModuleDefinition module, BaseNode node) { var split = xmlType.Split(':'); if (split.Length > 2) @@ -68,7 +70,7 @@ public static TypeReference GetTypeReference(XamlCache cache, string xmlType, Mo name = split[0]; } var namespaceuri = node.NamespaceResolver.LookupNamespace(prefix) ?? ""; - return GetTypeReference(new XmlType(namespaceuri, name, null), cache, module, node as IXmlLineInfo); + return GetTypeReference(new XmlType(namespaceuri, name, null), tryExtensionFirst, cache, module, node as IXmlLineInfo); } public static TypeReference GetTypeReference(XamlCache cache, string namespaceURI, string typename, ModuleDefinition module, IXmlLineInfo xmlInfo) @@ -77,6 +79,9 @@ public static TypeReference GetTypeReference(XamlCache cache, string namespaceUR } public static bool TryGetTypeReference(this XmlType xmlType, XamlCache cache, ModuleDefinition module, IXmlLineInfo xmlInfo, out TypeReference typeReference) + => TryGetTypeReference(xmlType, true, cache, module, xmlInfo, out typeReference); + + public static bool TryGetTypeReference(this XmlType xmlType, bool tryExtensionFirst, XamlCache cache, ModuleDefinition module, IXmlLineInfo xmlInfo, out TypeReference typeReference) { IList xmlnsDefinitions = cache.GetXmlsDefinitions(module, GatherXmlnsDefinitionAttributes); @@ -89,7 +94,7 @@ public static bool TryGetTypeReference(this XmlType xmlType, XamlCache cache, Mo if (type is not null && type.IsPublicOrVisibleInternal(module)) return type; return null; - }); + }, tryExtensionFirst); if (type != null && typeArguments != null && type.HasGenericParameters) type = module.ImportReference(type).MakeGenericInstanceType(typeArguments.Select(x => x.GetTypeReference(cache, module, xmlInfo)).ToArray()); @@ -98,8 +103,11 @@ public static bool TryGetTypeReference(this XmlType xmlType, XamlCache cache, Mo } public static TypeReference GetTypeReference(this XmlType xmlType, XamlCache cache, ModuleDefinition module, IXmlLineInfo xmlInfo) + => GetTypeReference(xmlType, true, cache, module, xmlInfo); + + public static TypeReference GetTypeReference(this XmlType xmlType, bool tryExtensionFirst, XamlCache cache, ModuleDefinition module, IXmlLineInfo xmlInfo) { - if (TryGetTypeReference(xmlType, cache, module, xmlInfo, out TypeReference typeReference)) + if (TryGetTypeReference(xmlType, tryExtensionFirst, cache, module, xmlInfo, out TypeReference typeReference)) return typeReference; throw new BuildException(BuildExceptionCode.TypeResolution, xmlInfo, null, $"{xmlType.NamespaceUri}:{xmlType.Name}"); diff --git a/src/Controls/src/Core/IXamlTypeResolver.cs b/src/Controls/src/Core/IXamlTypeResolver.cs index 49c3e175d499..d19766fb0b01 100644 --- a/src/Controls/src/Core/IXamlTypeResolver.cs +++ b/src/Controls/src/Core/IXamlTypeResolver.cs @@ -6,6 +6,7 @@ namespace Microsoft.Maui.Controls.Xaml public interface IXamlTypeResolver { Type Resolve(string qualifiedTypeName, IServiceProvider serviceProvider = null); + Type Resolve(string qualifiedTypeName, bool tryExtensionFirst, IServiceProvider serviceProvider = null); bool TryResolve(string qualifiedTypeName, out Type type); } } \ No newline at end of file diff --git a/src/Controls/src/Core/PublicAPI/net-android/PublicAPI.Unshipped.txt b/src/Controls/src/Core/PublicAPI/net-android/PublicAPI.Unshipped.txt index 96b430d94815..30aaa4cd592b 100644 --- a/src/Controls/src/Core/PublicAPI/net-android/PublicAPI.Unshipped.txt +++ b/src/Controls/src/Core/PublicAPI/net-android/PublicAPI.Unshipped.txt @@ -17,6 +17,7 @@ static readonly Microsoft.Maui.Controls.PointerGestureRecognizer.PointerReleased static readonly Microsoft.Maui.Controls.PointerGestureRecognizer.PointerReleasedCommandProperty -> Microsoft.Maui.Controls.BindableProperty! ~Microsoft.Maui.Controls.Accelerator.Key.get -> string *REMOVED*override Microsoft.Maui.Controls.RefreshView.MeasureOverride(double widthConstraint, double heightConstraint) -> Microsoft.Maui.Graphics.Size +~Microsoft.Maui.Controls.Xaml.IXamlTypeResolver.Resolve(string qualifiedTypeName, bool tryExtensionFirst, System.IServiceProvider serviceProvider = null) -> System.Type Microsoft.Maui.Controls.Border.~Border() -> void Microsoft.Maui.Controls.IWindowCreator Microsoft.Maui.Controls.IWindowCreator.CreateWindow(Microsoft.Maui.Controls.Application! app, Microsoft.Maui.IActivationState? activationState) -> Microsoft.Maui.Controls.Window! diff --git a/src/Controls/src/Core/PublicAPI/net-ios/PublicAPI.Unshipped.txt b/src/Controls/src/Core/PublicAPI/net-ios/PublicAPI.Unshipped.txt index 514481cfa641..517f132e2abc 100644 --- a/src/Controls/src/Core/PublicAPI/net-ios/PublicAPI.Unshipped.txt +++ b/src/Controls/src/Core/PublicAPI/net-ios/PublicAPI.Unshipped.txt @@ -61,6 +61,7 @@ static Microsoft.Maui.Controls.Shapes.Matrix.operator ==(Microsoft.Maui.Controls override Microsoft.Maui.Controls.View.ChangeVisualState() -> void Microsoft.Maui.Controls.Handlers.BoxViewHandler Microsoft.Maui.Controls.Handlers.BoxViewHandler.BoxViewHandler() -> void +~Microsoft.Maui.Controls.Xaml.IXamlTypeResolver.Resolve(string qualifiedTypeName, bool tryExtensionFirst, System.IServiceProvider serviceProvider = null) -> System.Type ~override Microsoft.Maui.Controls.Handlers.Items.CarouselViewController.DetermineCellReuseId(Foundation.NSIndexPath indexPath) -> string ~override Microsoft.Maui.Controls.ImageButton.OnPropertyChanged(string propertyName = null) -> void ~override Microsoft.Maui.Controls.Handlers.Compatibility.PhoneFlyoutPageRenderer.ViewWillTransitionToSize(CoreGraphics.CGSize toSize, UIKit.IUIViewControllerTransitionCoordinator coordinator) -> void diff --git a/src/Controls/src/Core/PublicAPI/net-maccatalyst/PublicAPI.Unshipped.txt b/src/Controls/src/Core/PublicAPI/net-maccatalyst/PublicAPI.Unshipped.txt index 32354ee057b5..6eb4afd99bfe 100644 --- a/src/Controls/src/Core/PublicAPI/net-maccatalyst/PublicAPI.Unshipped.txt +++ b/src/Controls/src/Core/PublicAPI/net-maccatalyst/PublicAPI.Unshipped.txt @@ -17,6 +17,7 @@ static readonly Microsoft.Maui.Controls.PointerGestureRecognizer.PointerReleased static readonly Microsoft.Maui.Controls.PointerGestureRecognizer.PointerReleasedCommandProperty -> Microsoft.Maui.Controls.BindableProperty! ~Microsoft.Maui.Controls.Accelerator.Key.get -> string *REMOVED*override Microsoft.Maui.Controls.RefreshView.MeasureOverride(double widthConstraint, double heightConstraint) -> Microsoft.Maui.Graphics.Size +~Microsoft.Maui.Controls.Xaml.IXamlTypeResolver.Resolve(string qualifiedTypeName, bool tryExtensionFirst, System.IServiceProvider serviceProvider = null) -> System.Type Microsoft.Maui.Controls.Border.~Border() -> void Microsoft.Maui.Controls.IWindowCreator Microsoft.Maui.Controls.IWindowCreator.CreateWindow(Microsoft.Maui.Controls.Application! app, Microsoft.Maui.IActivationState? activationState) -> Microsoft.Maui.Controls.Window! diff --git a/src/Controls/src/Core/PublicAPI/net-tizen/PublicAPI.Unshipped.txt b/src/Controls/src/Core/PublicAPI/net-tizen/PublicAPI.Unshipped.txt index b532d073bb22..5987d90a116c 100644 --- a/src/Controls/src/Core/PublicAPI/net-tizen/PublicAPI.Unshipped.txt +++ b/src/Controls/src/Core/PublicAPI/net-tizen/PublicAPI.Unshipped.txt @@ -1,4 +1,5 @@ -#nullable enable +#nullable enable +~Microsoft.Maui.Controls.Xaml.IXamlTypeResolver.Resolve(string qualifiedTypeName, bool tryExtensionFirst, System.IServiceProvider serviceProvider = null) -> System.Type *REMOVED*~Microsoft.Maui.Controls.Accelerator.Modifiers.set -> void *REMOVED*~Microsoft.Maui.Controls.Accelerator.Keys.set -> void Microsoft.Maui.Controls.PointerGestureRecognizer.PointerPressed -> System.EventHandler? diff --git a/src/Controls/src/Core/PublicAPI/net-windows/PublicAPI.Unshipped.txt b/src/Controls/src/Core/PublicAPI/net-windows/PublicAPI.Unshipped.txt index 3dc9813a8d5d..13a7e1afc70f 100644 --- a/src/Controls/src/Core/PublicAPI/net-windows/PublicAPI.Unshipped.txt +++ b/src/Controls/src/Core/PublicAPI/net-windows/PublicAPI.Unshipped.txt @@ -17,6 +17,7 @@ static readonly Microsoft.Maui.Controls.PointerGestureRecognizer.PointerReleased static readonly Microsoft.Maui.Controls.PointerGestureRecognizer.PointerReleasedCommandProperty -> Microsoft.Maui.Controls.BindableProperty! ~Microsoft.Maui.Controls.Accelerator.Key.get -> string *REMOVED*override Microsoft.Maui.Controls.RefreshView.MeasureOverride(double widthConstraint, double heightConstraint) -> Microsoft.Maui.Graphics.Size +~Microsoft.Maui.Controls.Xaml.IXamlTypeResolver.Resolve(string qualifiedTypeName, bool tryExtensionFirst, System.IServiceProvider serviceProvider = null) -> System.Type Microsoft.Maui.Controls.Border.~Border() -> void Microsoft.Maui.Controls.InputView.IsTextPredictionEnabled.get -> bool Microsoft.Maui.Controls.InputView.IsTextPredictionEnabled.set -> void diff --git a/src/Controls/src/Core/PublicAPI/net/PublicAPI.Unshipped.txt b/src/Controls/src/Core/PublicAPI/net/PublicAPI.Unshipped.txt index d5f415061ff6..cfdcbac22d2f 100644 --- a/src/Controls/src/Core/PublicAPI/net/PublicAPI.Unshipped.txt +++ b/src/Controls/src/Core/PublicAPI/net/PublicAPI.Unshipped.txt @@ -17,6 +17,7 @@ static readonly Microsoft.Maui.Controls.PointerGestureRecognizer.PointerReleased static readonly Microsoft.Maui.Controls.PointerGestureRecognizer.PointerReleasedCommandProperty -> Microsoft.Maui.Controls.BindableProperty! ~Microsoft.Maui.Controls.Accelerator.Key.get -> string *REMOVED*override Microsoft.Maui.Controls.RefreshView.MeasureOverride(double widthConstraint, double heightConstraint) -> Microsoft.Maui.Graphics.Size +~Microsoft.Maui.Controls.Xaml.IXamlTypeResolver.Resolve(string qualifiedTypeName, bool tryExtensionFirst, System.IServiceProvider serviceProvider = null) -> System.Type Microsoft.Maui.Controls.Border.~Border() -> void Microsoft.Maui.Controls.InputView.IsTextPredictionEnabled.get -> bool Microsoft.Maui.Controls.InputView.IsTextPredictionEnabled.set -> void diff --git a/src/Controls/src/Core/PublicAPI/netstandard/PublicAPI.Unshipped.txt b/src/Controls/src/Core/PublicAPI/netstandard/PublicAPI.Unshipped.txt index a3b5d5e0b57c..a93dd42168b4 100644 --- a/src/Controls/src/Core/PublicAPI/netstandard/PublicAPI.Unshipped.txt +++ b/src/Controls/src/Core/PublicAPI/netstandard/PublicAPI.Unshipped.txt @@ -18,6 +18,7 @@ static readonly Microsoft.Maui.Controls.PointerGestureRecognizer.PointerReleased Microsoft.Maui.Controls.Element.ClearLogicalChildren() -> void ~Microsoft.Maui.Controls.Accelerator.Key.get -> string *REMOVED*override Microsoft.Maui.Controls.RefreshView.MeasureOverride(double widthConstraint, double heightConstraint) -> Microsoft.Maui.Graphics.Size +~Microsoft.Maui.Controls.Xaml.IXamlTypeResolver.Resolve(string qualifiedTypeName, bool tryExtensionFirst, System.IServiceProvider serviceProvider = null) -> System.Type Microsoft.Maui.Controls.Border.~Border() -> void Microsoft.Maui.Controls.InputView.IsTextPredictionEnabled.get -> bool Microsoft.Maui.Controls.InputView.IsTextPredictionEnabled.set -> void diff --git a/src/Controls/src/Xaml/ApplyPropertiesVisitor.cs b/src/Controls/src/Xaml/ApplyPropertiesVisitor.cs index 0f3ac4d42b54..e0b7bc650699 100644 --- a/src/Controls/src/Xaml/ApplyPropertiesVisitor.cs +++ b/src/Controls/src/Xaml/ApplyPropertiesVisitor.cs @@ -316,7 +316,7 @@ static bool GetRealNameAndType(ref Type elementType, string namespaceURI, ref st var typename = localname.Substring(0, dotIdx); localname = localname.Substring(dotIdx + 1); XamlParseException xpe; - elementType = XamlParser.GetElementType(new XmlType(namespaceURI, typename, null), lineInfo, + elementType = XamlParser.GetElementType(new XmlType(namespaceURI, typename, null), true, lineInfo, rootElement.GetType().Assembly, out xpe); if (xpe != null) diff --git a/src/Controls/src/Xaml/CreateValuesVisitor.cs b/src/Controls/src/Xaml/CreateValuesVisitor.cs index fb0f298f4d59..2f59e2cd6a01 100644 --- a/src/Controls/src/Xaml/CreateValuesVisitor.cs +++ b/src/Controls/src/Xaml/CreateValuesVisitor.cs @@ -43,7 +43,7 @@ public void Visit(ElementNode node, INode parentNode) { object value = null; - var type = XamlParser.GetElementType(node.XmlType, node, Context.RootElement?.GetType().Assembly, + var type = XamlParser.GetElementType(node.XmlType, true, node, Context.RootElement?.GetType().Assembly, out XamlParseException xpe); if (xpe != null) { diff --git a/src/Controls/src/Xaml/MarkupExtensions/StaticExtension.cs b/src/Controls/src/Xaml/MarkupExtensions/StaticExtension.cs index 2c8101430eb8..cfddb577b92a 100644 --- a/src/Controls/src/Xaml/MarkupExtensions/StaticExtension.cs +++ b/src/Controls/src/Xaml/MarkupExtensions/StaticExtension.cs @@ -24,7 +24,7 @@ public object ProvideValue(IServiceProvider serviceProvider) var typename = Member.Substring(0, dotIdx); var membername = Member.Substring(dotIdx + 1); - var type = typeResolver.Resolve(typename, serviceProvider); + var type = typeResolver.Resolve(typename, tryExtensionFirst: false, serviceProvider: serviceProvider); var pinfo = type.GetRuntimeProperties().FirstOrDefault(pi => pi.Name == membername && pi.GetMethod.IsStatic); if (pinfo != null) diff --git a/src/Controls/src/Xaml/MarkupExtensions/TypeExtension.cs b/src/Controls/src/Xaml/MarkupExtensions/TypeExtension.cs index 1bdde80cb3a2..2466676d9848 100644 --- a/src/Controls/src/Xaml/MarkupExtensions/TypeExtension.cs +++ b/src/Controls/src/Xaml/MarkupExtensions/TypeExtension.cs @@ -20,7 +20,7 @@ public Type ProvideValue(IServiceProvider serviceProvider) throw new XamlParseException("TypeName isn't set.", li); } - return typeResolver.Resolve(TypeName, serviceProvider); + return typeResolver.Resolve(TypeName, tryExtensionFirst: false, serviceProvider: serviceProvider); } object IMarkupExtension.ProvideValue(IServiceProvider serviceProvider) diff --git a/src/Controls/src/Xaml/XamlParser.cs b/src/Controls/src/Xaml/XamlParser.cs index f5a7b1f3c1fa..f2d2c3bc5d68 100644 --- a/src/Controls/src/Xaml/XamlParser.cs +++ b/src/Controls/src/Xaml/XamlParser.cs @@ -356,7 +356,7 @@ static void GatherXmlnsDefinitionAttributes() } } - public static Type GetElementType(XmlType xmlType, IXmlLineInfo xmlInfo, Assembly currentAssembly, + public static Type GetElementType(XmlType xmlType, bool tryExtensionFirst, IXmlLineInfo xmlInfo, Assembly currentAssembly, out XamlParseException exception) { bool hasRetriedNsSearch = false; @@ -374,7 +374,7 @@ public static Type GetElementType(XmlType xmlType, IXmlLineInfo xmlInfo, Assembl if (t is not null && t.IsPublicOrVisibleInternal(currentAssembly)) return t; return null; - }); + }, tryExtensionFirst); var typeArguments = xmlType.TypeArguments; exception = null; @@ -398,7 +398,7 @@ public static Type GetElementType(XmlType xmlType, IXmlLineInfo xmlInfo, Assembl XamlParseException innerexception = null; var args = typeArguments.Select(delegate (XmlType xmltype) { - var t = GetElementType(xmltype, xmlInfo, currentAssembly, out XamlParseException xpe); + var t = GetElementType(xmltype, true, xmlInfo, currentAssembly, out XamlParseException xpe); if (xpe != null) { innerexception = xpe; diff --git a/src/Controls/src/Xaml/XamlServiceProvider.cs b/src/Controls/src/Xaml/XamlServiceProvider.cs index 23bf38738b32..d3c9ad3f2484 100644 --- a/src/Controls/src/Xaml/XamlServiceProvider.cs +++ b/src/Controls/src/Xaml/XamlServiceProvider.cs @@ -177,8 +177,11 @@ internal XamlTypeResolver(IXmlNamespaceResolver namespaceResolver, GetTypeFromXm } Type IXamlTypeResolver.Resolve(string qualifiedTypeName, IServiceProvider serviceProvider) + => ((IXamlTypeResolver)this).Resolve(qualifiedTypeName, true, serviceProvider); + + Type IXamlTypeResolver.Resolve(string qualifiedTypeName, bool tryExtensionFirst, IServiceProvider serviceProvider) { - var type = Resolve(qualifiedTypeName, serviceProvider, out XamlParseException e); + var type = Resolve(qualifiedTypeName, tryExtensionFirst, serviceProvider, out XamlParseException e); if (e != null) throw e; return type; @@ -186,18 +189,18 @@ Type IXamlTypeResolver.Resolve(string qualifiedTypeName, IServiceProvider servic bool IXamlTypeResolver.TryResolve(string qualifiedTypeName, out Type type) { - type = Resolve(qualifiedTypeName, null, out XamlParseException exception); + type = Resolve(qualifiedTypeName, true, null, out XamlParseException exception); return exception == null; } internal bool TryResolve(XmlType xmlType, out Type type) { XamlParseException exception; - type = getTypeFromXmlName(xmlType, null, currentAssembly, out exception); + type = getTypeFromXmlName(xmlType, true, null, currentAssembly, out exception); return exception == null; } - Type Resolve(string qualifiedTypeName, IServiceProvider serviceProvider, out XamlParseException exception) + Type Resolve(string qualifiedTypeName, bool tryExtensionFirst, IServiceProvider serviceProvider, out XamlParseException exception) { exception = null; var split = qualifiedTypeName.Split(':'); @@ -230,10 +233,10 @@ Type Resolve(string qualifiedTypeName, IServiceProvider serviceProvider, out Xam return null; } - return getTypeFromXmlName(new XmlType(namespaceuri, name, null), xmlLineInfo, currentAssembly, out exception); + return getTypeFromXmlName(new XmlType(namespaceuri, name, null), tryExtensionFirst, xmlLineInfo, currentAssembly, out exception); } - internal delegate Type GetTypeFromXmlName(XmlType xmlType, IXmlLineInfo xmlInfo, Assembly currentAssembly, out XamlParseException exception); + internal delegate Type GetTypeFromXmlName(XmlType xmlType, bool tryExtensionFirst, IXmlLineInfo xmlInfo, Assembly currentAssembly, out XamlParseException exception); } class XamlRootObjectProvider : IRootObjectProvider diff --git a/src/Controls/src/Xaml/XmlTypeXamlExtensions.cs b/src/Controls/src/Xaml/XmlTypeXamlExtensions.cs index 95720dc64325..10039ed0a2c4 100644 --- a/src/Controls/src/Xaml/XmlTypeXamlExtensions.cs +++ b/src/Controls/src/Xaml/XmlTypeXamlExtensions.cs @@ -37,7 +37,8 @@ static class XmlTypeXamlExtensions this XmlType xmlType, IEnumerable xmlnsDefinitions, string defaultAssemblyName, - Func<(string typeName, string clrNamespace, string assemblyName), T> refFromTypeInfo) + Func<(string typeName, string clrNamespace, string assemblyName), T> refFromTypeInfo, + bool tryExtensionFirst = true) where T : class { var lookupAssemblies = new List(); @@ -61,7 +62,7 @@ static class XmlTypeXamlExtensions } var lookupNames = new List(); - if (elementName != "DataTemplate" && !elementName.EndsWith("Extension", StringComparison.Ordinal)) + if (elementName != "DataTemplate" && !elementName.EndsWith("Extension", StringComparison.Ordinal) && tryExtensionFirst) lookupNames.Add(elementName + "Extension"); lookupNames.Add(elementName); diff --git a/src/Controls/tests/Xaml.UnitTests/Issues/Maui11833.xaml b/src/Controls/tests/Xaml.UnitTests/Issues/Maui11833.xaml new file mode 100644 index 000000000000..d522d9925b6a --- /dev/null +++ b/src/Controls/tests/Xaml.UnitTests/Issues/Maui11833.xaml @@ -0,0 +1,11 @@ + + + + + + + + \ No newline at end of file diff --git a/src/Controls/tests/Xaml.UnitTests/Issues/Maui11833.xaml.cs b/src/Controls/tests/Xaml.UnitTests/Issues/Maui11833.xaml.cs new file mode 100644 index 000000000000..36016ceb9ac5 --- /dev/null +++ b/src/Controls/tests/Xaml.UnitTests/Issues/Maui11833.xaml.cs @@ -0,0 +1,25 @@ +using Microsoft.Maui.Controls.Core.UnitTests; +using NUnit.Framework; + +namespace Microsoft.Maui.Controls.Xaml.UnitTests +{ + public partial class Maui11833 : ContentPage + { + public Maui11833() => InitializeComponent(); + public Maui11833(bool useCompiledXaml) + { + //this stub will be replaced at compile time + } + + [TestFixture] + class Tests + { + [Test] + public void xStaticBinding([Values(false, true)] bool useCompiledXaml) + { + var page = new Maui11833(useCompiledXaml); + } + } + } + +} \ No newline at end of file diff --git a/src/Controls/tests/Xaml.UnitTests/LoaderTests.cs b/src/Controls/tests/Xaml.UnitTests/LoaderTests.cs index 4ad6d3d0376f..0373e50091e5 100644 --- a/src/Controls/tests/Xaml.UnitTests/LoaderTests.cs +++ b/src/Controls/tests/Xaml.UnitTests/LoaderTests.cs @@ -792,7 +792,7 @@ public void StyleWithoutTargetTypeThrows() public void BindingIsResolvedAsBindingExtension() // https://github.com/xamarin/Microsoft.Maui.Controls/issues/3606#issuecomment-422377338 { - var bindingType = XamlParser.GetElementType(new XmlType("http://schemas.microsoft.com/dotnet/2021/maui", "Binding", null), null, null, out var ex); + var bindingType = XamlParser.GetElementType(new XmlType("http://schemas.microsoft.com/dotnet/2021/maui", "Binding", null), true, null, null, out var ex); Assert.That(ex, Is.Null); Assert.That(bindingType, Is.EqualTo(typeof(BindingExtension))); var module = ModuleDefinition.CreateModule("foo", new ModuleParameters() diff --git a/src/Controls/tests/Xaml.UnitTests/TypeExtensionTests.cs b/src/Controls/tests/Xaml.UnitTests/TypeExtensionTests.cs index 7177d199fde5..28674f086e22 100644 --- a/src/Controls/tests/Xaml.UnitTests/TypeExtensionTests.cs +++ b/src/Controls/tests/Xaml.UnitTests/TypeExtensionTests.cs @@ -51,5 +51,12 @@ public void TestWithExplicitTypeName() var markupString = @"{x:Type TypeName=sys:String}"; Assert.AreEqual(typeof(string), (new MarkupExtensionParser()).ParseExpression(ref markupString, serviceProvider)); } + + [Test] + public void DontExpandToExtension() + { + var markupString = @"{x:Type Binding}"; + Assert.AreEqual(typeof(Binding), (new MarkupExtensionParser()).ParseExpression(ref markupString, serviceProvider)); + } } } \ No newline at end of file