diff --git a/Xamarin.Forms.Core/TypeTypeConverter.cs b/Xamarin.Forms.Core/TypeTypeConverter.cs
index 14e113f7287..e08b80d67b5 100644
--- a/Xamarin.Forms.Core/TypeTypeConverter.cs
+++ b/Xamarin.Forms.Core/TypeTypeConverter.cs
@@ -5,31 +5,24 @@
namespace Xamarin.Forms
{
- [Xaml.ProvideCompiled("Xamarin.Forms.Core.XamlC.TypeTypeConverter")]
- [Xaml.TypeConversion(typeof(Type))]
+ [ProvideCompiled("Xamarin.Forms.Core.XamlC.TypeTypeConverter")]
+ [TypeConversion(typeof(Type))]
public sealed class TypeTypeConverter : TypeConverter, IExtendedTypeConverter
{
- [Obsolete("IExtendedTypeConverter.ConvertFrom is obsolete as of version 2.2.0. Please use ConvertFromInvariantString (string, IServiceProvider) instead.")]
- [EditorBrowsable(EditorBrowsableState.Never)]
- object IExtendedTypeConverter.ConvertFrom(CultureInfo culture, object value, IServiceProvider serviceProvider)
- {
- return ((IExtendedTypeConverter)this).ConvertFromInvariantString((string)value, serviceProvider);
- }
-
object IExtendedTypeConverter.ConvertFromInvariantString(string value, IServiceProvider serviceProvider)
{
if (serviceProvider == null)
- throw new ArgumentNullException("serviceProvider");
- var typeResolver = serviceProvider.GetService(typeof(IXamlTypeResolver)) as IXamlTypeResolver;
- if (typeResolver == null)
+ throw new ArgumentNullException(nameof(serviceProvider));
+ if (!(serviceProvider.GetService(typeof(IXamlTypeResolver)) is IXamlTypeResolver typeResolver))
throw new ArgumentException("No IXamlTypeResolver in IServiceProvider");
return typeResolver.Resolve(value, serviceProvider);
}
- public override object ConvertFromInvariantString(string value)
- {
- throw new NotImplementedException();
- }
+ public override object ConvertFromInvariantString(string value) => throw new NotImplementedException();
+
+ [Obsolete("IExtendedTypeConverter.ConvertFrom is obsolete as of version 2.2.0. Please use ConvertFromInvariantString (string, IServiceProvider) instead.")]
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ object IExtendedTypeConverter.ConvertFrom(CultureInfo culture, object value, IServiceProvider serviceProvider) => ((IExtendedTypeConverter)this).ConvertFromInvariantString((string)value, serviceProvider);
}
}
\ No newline at end of file
diff --git a/Xamarin.Forms.Xaml.UnitTests/AppResources/Colors.xaml b/Xamarin.Forms.Xaml.UnitTests/AppResources/Colors.xaml
index 93b60c303ca..6eb475d06b0 100644
--- a/Xamarin.Forms.Xaml.UnitTests/AppResources/Colors.xaml
+++ b/Xamarin.Forms.Xaml.UnitTests/AppResources/Colors.xaml
@@ -1,7 +1,8 @@
+ xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
+ xmlns:local="using:Xamarin.Forms.Xaml.UnitTests">
#FF4B14
#99253748
#253748
@@ -19,4 +20,8 @@
#C0C0C0
#4d4d4d
#999999
+
+
\ No newline at end of file
diff --git a/Xamarin.Forms.Xaml.UnitTests/AppResources/CompiledColors.xaml b/Xamarin.Forms.Xaml.UnitTests/AppResources/CompiledColors.xaml
index d859c22e215..e75eed0e23c 100644
--- a/Xamarin.Forms.Xaml.UnitTests/AppResources/CompiledColors.xaml
+++ b/Xamarin.Forms.Xaml.UnitTests/AppResources/CompiledColors.xaml
@@ -2,7 +2,9 @@
+ xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
+ xmlns:local="using:Xamarin.Forms.Xaml.UnitTests">
+
#FF4B14
#99253748
#253748
@@ -20,4 +22,8 @@
#C0C0C0
#4d4d4d
#999999
+
+
\ No newline at end of file
diff --git a/Xamarin.Forms.Xaml.UnitTests/Issues/Gh7531.xaml b/Xamarin.Forms.Xaml.UnitTests/Issues/Gh7531.xaml
new file mode 100644
index 00000000000..f5bd609a4c3
--- /dev/null
+++ b/Xamarin.Forms.Xaml.UnitTests/Issues/Gh7531.xaml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/Xamarin.Forms.Xaml.UnitTests/Issues/Gh7531.xaml.cs b/Xamarin.Forms.Xaml.UnitTests/Issues/Gh7531.xaml.cs
new file mode 100644
index 00000000000..c8bf1bff705
--- /dev/null
+++ b/Xamarin.Forms.Xaml.UnitTests/Issues/Gh7531.xaml.cs
@@ -0,0 +1,32 @@
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT License.
+using NUnit.Framework;
+using Xamarin.Forms.Core.UnitTests;
+
+namespace Xamarin.Forms.Xaml.UnitTests
+{
+ public partial class Gh7531 : ContentPage
+ {
+ public Gh7531() => InitializeComponent();
+ public Gh7531(bool useCompiledXaml)
+ {
+ //this stub will be replaced at compile time
+ }
+
+ [TestFixture]
+ class Tests
+ {
+ [SetUp] public void Setup() => Device.PlatformServices = new MockPlatformServices();
+ [TearDown] public void TearDown() => Device.PlatformServices = null;
+
+ [Test]
+ public void XamlOnlyResourceResolvesLocalAssembly([Values(false, true)]bool useCompiledXaml)
+ {
+ Gh7531 layout = null;
+ Assert.DoesNotThrow(() => layout = new Gh7531(useCompiledXaml));
+ var style = ((ResourceDictionary)layout.Resources["Colors"])["style"] as Style;
+ Assert.That(style.TargetType, Is.EqualTo(typeof(Gh7531)));
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Xamarin.Forms.Xaml/HydrationContext.cs b/Xamarin.Forms.Xaml/HydrationContext.cs
index 9599772c615..fdcaf97edcc 100644
--- a/Xamarin.Forms.Xaml/HydrationContext.cs
+++ b/Xamarin.Forms.Xaml/HydrationContext.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using System.Reflection;
namespace Xamarin.Forms.Xaml
{
@@ -16,5 +17,6 @@ public HydrationContext()
public HydrationContext ParentContext { get; set; }
public Action ExceptionHandler { get; set; }
public object RootElement { get; set; }
+ public Assembly RootAssembly { get; internal set; }
}
}
\ No newline at end of file
diff --git a/Xamarin.Forms.Xaml/ResourcesLoader.cs b/Xamarin.Forms.Xaml/ResourcesLoader.cs
index 58d5f0f6e06..2da537c41d8 100644
--- a/Xamarin.Forms.Xaml/ResourcesLoader.cs
+++ b/Xamarin.Forms.Xaml/ResourcesLoader.cs
@@ -32,7 +32,7 @@ class ResourcesLoader : IResourcesLoader
if (stream == null)
throw new XamlParseException($"No resource found for '{resourceId}'.", lineInfo);
using (var reader = new StreamReader(stream)) {
- rd.LoadFromXaml(reader.ReadToEnd());
+ rd.LoadFromXaml(reader.ReadToEnd(), assembly);
return rd;
}
}
diff --git a/Xamarin.Forms.Xaml/ViewExtensions.cs b/Xamarin.Forms.Xaml/ViewExtensions.cs
index bea83890328..d388cdbdb2a 100644
--- a/Xamarin.Forms.Xaml/ViewExtensions.cs
+++ b/Xamarin.Forms.Xaml/ViewExtensions.cs
@@ -26,6 +26,7 @@
// THE SOFTWARE.
using System;
+using System.Reflection;
namespace Xamarin.Forms.Xaml
{
@@ -42,5 +43,11 @@ public static TXaml LoadFromXaml(this TXaml view, string xaml)
XamlLoader.Load(view, xaml);
return view;
}
+
+ internal static TXaml LoadFromXaml(this TXaml view, string xaml, Assembly rootAssembly)
+ {
+ XamlLoader.Load(view, xaml, rootAssembly);
+ return view;
+ }
}
}
\ No newline at end of file
diff --git a/Xamarin.Forms.Xaml/XamlLoader.cs b/Xamarin.Forms.Xaml/XamlLoader.cs
index f821fe9d951..5a4f11e8b1f 100644
--- a/Xamarin.Forms.Xaml/XamlLoader.cs
+++ b/Xamarin.Forms.Xaml/XamlLoader.cs
@@ -71,8 +71,10 @@ public static void Load(object view, Type callingType)
}
public static void Load(object view, string xaml) => Load(view, xaml, false);
+ public static void Load(object view, string xaml, bool useDesignProperties) => Load(view, xaml, null, useDesignProperties);
+ public static void Load(object view, string xaml, Assembly rootAssembly) => Load(view, xaml, rootAssembly, false);
- public static void Load(object view, string xaml, bool useDesignProperties)
+ public static void Load(object view, string xaml, Assembly rootAssembly, bool useDesignProperties)
{
using (var textReader = new StringReader(xaml))
using (var reader = XmlReader.Create(textReader)) {
@@ -95,7 +97,7 @@ public static void Load(object view, string xaml, bool useDesignProperties)
void ehandler(Exception e) => ResourceLoader.ExceptionHandler2?.Invoke((e, XamlFilePathAttribute.GetFilePathForObject(view)));
Visit(rootnode, new HydrationContext {
RootElement = view,
-
+ RootAssembly = rootAssembly ?? view.GetType().GetTypeInfo().Assembly,
ExceptionHandler = doNotThrow ? ehandler : (Action)null
}, useDesignProperties);
break;
diff --git a/Xamarin.Forms.Xaml/XamlServiceProvider.cs b/Xamarin.Forms.Xaml/XamlServiceProvider.cs
index b6d2000b16b..849085722d0 100644
--- a/Xamarin.Forms.Xaml/XamlServiceProvider.cs
+++ b/Xamarin.Forms.Xaml/XamlServiceProvider.cs
@@ -17,11 +17,8 @@ internal XamlServiceProvider(INode node, HydrationContext context)
IProvideValueTarget = new XamlValueTargetProvider(targetObject, node, context, null);
if (context != null)
IRootObjectProvider = new XamlRootObjectProvider(context.RootElement);
- if (context != null && node != null)
- {
- IXamlTypeResolver = new XamlTypeResolver(node.NamespaceResolver, XamlParser.GetElementType,
- context.RootElement.GetType().GetTypeInfo().Assembly);
-
+ if (context != null && node != null) {
+ IXamlTypeResolver = new XamlTypeResolver(node.NamespaceResolver, XamlParser.GetElementType, context.RootAssembly);
Add(typeof(IReferenceProvider), new ReferenceProvider(node));
}
@@ -31,52 +28,49 @@ internal XamlServiceProvider(INode node, HydrationContext context)
IValueConverterProvider = new ValueConverterProvider();
}
- public XamlServiceProvider()
- {
- IValueConverterProvider = new ValueConverterProvider();
- }
+ public XamlServiceProvider() => IValueConverterProvider = new ValueConverterProvider();
internal IProvideValueTarget IProvideValueTarget
{
- get { return (IProvideValueTarget)GetService(typeof (IProvideValueTarget)); }
- set { services[typeof (IProvideValueTarget)] = value; }
+ get => (IProvideValueTarget)GetService(typeof(IProvideValueTarget));
+ set => services[typeof(IProvideValueTarget)] = value;
}
internal IXamlTypeResolver IXamlTypeResolver
{
- get { return (IXamlTypeResolver)GetService(typeof (IXamlTypeResolver)); }
- set { services[typeof (IXamlTypeResolver)] = value; }
+ get => (IXamlTypeResolver)GetService(typeof(IXamlTypeResolver));
+ set => services[typeof(IXamlTypeResolver)] = value;
}
internal IRootObjectProvider IRootObjectProvider
{
- get { return (IRootObjectProvider)GetService(typeof (IRootObjectProvider)); }
- set { services[typeof (IRootObjectProvider)] = value; }
+ get => (IRootObjectProvider)GetService(typeof(IRootObjectProvider));
+ set => services[typeof(IRootObjectProvider)] = value;
}
internal IXmlLineInfoProvider IXmlLineInfoProvider
{
- get { return (IXmlLineInfoProvider)GetService(typeof (IXmlLineInfoProvider)); }
- set { services[typeof (IXmlLineInfoProvider)] = value; }
- }
-
- [Obsolete]
- [EditorBrowsable(EditorBrowsableState.Never)]
- internal INameScopeProvider INameScopeProvider
- {
- get { return (INameScopeProvider)GetService(typeof (INameScopeProvider)); }
- set { services[typeof (INameScopeProvider)] = value; }
+ get => (IXmlLineInfoProvider)GetService(typeof(IXmlLineInfoProvider));
+ set => services[typeof(IXmlLineInfoProvider)] = value;
}
internal IValueConverterProvider IValueConverterProvider
{
- get { return (IValueConverterProvider)GetService(typeof (IValueConverterProvider)); }
- set { services[typeof (IValueConverterProvider)] = value; }
+ get => (IValueConverterProvider)GetService(typeof(IValueConverterProvider));
+ set => services[typeof(IValueConverterProvider)] = value;
}
public object GetService(Type serviceType) => services.TryGetValue(serviceType, out var service) ? service : null;
public void Add(Type type, object service) => services.Add(type, service);
+
+ [Obsolete]
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ internal INameScopeProvider INameScopeProvider
+ {
+ get { return (INameScopeProvider)GetService(typeof(INameScopeProvider)); }
+ set { services[typeof(INameScopeProvider)] = value; }
+ }
}
class XamlValueTargetProvider : IProvideParentValues, IProvideValueTarget
@@ -227,7 +221,7 @@ Type Resolve(string qualifiedTypeName, IServiceProvider serviceProvider, out Xam
var namespaceuri = namespaceResolver.LookupNamespace(prefix);
if (namespaceuri == null) {
- exception = new XamlParseException(string.Format("No xmlns declaration for prefix \"{0}\"", prefix), xmlLineInfo);
+ exception = new XamlParseException($"No xmlns declaration for prefix \"{prefix}\"", xmlLineInfo);
return null;
}
@@ -239,20 +233,14 @@ Type Resolve(string qualifiedTypeName, IServiceProvider serviceProvider, out Xam
class XamlRootObjectProvider : IRootObjectProvider
{
- public XamlRootObjectProvider(object rootObject)
- {
- RootObject = rootObject;
- }
+ public XamlRootObjectProvider(object rootObject) => RootObject = rootObject;
public object RootObject { get; }
}
public class XmlLineInfoProvider : IXmlLineInfoProvider
{
- public XmlLineInfoProvider(IXmlLineInfo xmlLineInfo)
- {
- XmlLineInfo = xmlLineInfo;
- }
+ public XmlLineInfoProvider(IXmlLineInfo xmlLineInfo) => XmlLineInfo = xmlLineInfo;
public IXmlLineInfo XmlLineInfo { get; }
}