diff --git a/Xamarin.Forms.Core/StyleSheets/StyleSheet.cs b/Xamarin.Forms.Core/StyleSheets/StyleSheet.cs index a932ef9a4f7..426cb7837ed 100644 --- a/Xamarin.Forms.Core/StyleSheets/StyleSheet.cs +++ b/Xamarin.Forms.Core/StyleSheets/StyleSheet.cs @@ -15,6 +15,8 @@ public sealed class StyleSheet : IStyle { } + public Uri Source { get; internal set; } + internal IDictionary Styles { get; set; } = new Dictionary(); public static StyleSheet FromAssemblyResource(Assembly assembly, string resourceId, IXmlLineInfo lineInfo = null) diff --git a/Xamarin.Forms.Xaml.UnitTests/StyleSheet.xaml.cs b/Xamarin.Forms.Xaml.UnitTests/StyleSheet.xaml.cs index 2236e042af4..690b7ba16cc 100644 --- a/Xamarin.Forms.Xaml.UnitTests/StyleSheet.xaml.cs +++ b/Xamarin.Forms.Xaml.UnitTests/StyleSheet.xaml.cs @@ -1,8 +1,9 @@ using System; +using System.IO; +using System.Linq; +using System.Reflection; using NUnit.Framework; - using Xamarin.Forms.Core.UnitTests; -using NUnit.Framework.Constraints; namespace Xamarin.Forms.Xaml.UnitTests { @@ -42,6 +43,44 @@ public void StyleSheetsAreApplied(bool useCompiledXaml) Assert.That(layout.label0.TextColor, Is.EqualTo(Color.Azure)); Assert.That(layout.label0.BackgroundColor, Is.EqualTo(Color.AliceBlue)); } + + [TestCase(false), TestCase(true)] + public void StyleSheetSourceIsApplied(bool useCompiledXaml) + { + // Having a custom ResourceProvider forces the LoadFromXaml code path + // for both XamlC and non-XamlC + Xamarin.Forms.Internals.ResourceLoader.ResourceProvider = GetResource; + + var layout = new StyleSheet(useCompiledXaml); + + Assert.AreEqual("css/foo.css", layout.Resources.StyleSheets[0].Source.OriginalString); + + // Reset state to its initial + Xamarin.Forms.Internals.ResourceLoader.ResourceProvider = null; + DesignMode.IsDesignModeEnabled = false; + } + + string GetResource(AssemblyName name, string path) + { + var assembly = Assembly.Load(name); + var resourceId = assembly + .GetCustomAttributes() + .Where(x => x.Path == path) + .Select(x => x.ResourceId) + .FirstOrDefault(); + + if (!string.IsNullOrEmpty(resourceId)) + { + using (var stream = assembly.GetManifestResourceStream(resourceId)) + { + if (stream != null) + using (var reader = new StreamReader(stream)) + return reader.ReadToEnd(); + } + } + + return null; + } } } } \ No newline at end of file diff --git a/Xamarin.Forms.Xaml/MarkupExtensions/StyleSheetExtension.cs b/Xamarin.Forms.Xaml/MarkupExtensions/StyleSheetExtension.cs index ab01f63af56..faa68217ca7 100644 --- a/Xamarin.Forms.Xaml/MarkupExtensions/StyleSheetExtension.cs +++ b/Xamarin.Forms.Xaml/MarkupExtensions/StyleSheetExtension.cs @@ -35,7 +35,9 @@ object IValueProvider.ProvideValue(IServiceProvider serviceProvider) var rootTargetPath = XamlResourceIdAttribute.GetPathForType(rootObjectType); var resourcePath = ResourceDictionary.RDSourceTypeConverter.GetResourcePath(Source, rootTargetPath); var resString = DependencyService.Get().GetResource(resourcePath, rootObjectType.GetTypeInfo().Assembly, lineInfo); - return StyleSheet.FromString(resString); + var styleSheet = StyleSheet.FromString(resString); + styleSheet.Source = new Uri(resourcePath, UriKind.Relative); + return styleSheet; } if (!string.IsNullOrEmpty(Style)) {