diff --git a/samples/ControlCatalog/MainWindow.xaml b/samples/ControlCatalog/MainWindow.xaml index f39beced1a..7029273a84 100644 --- a/samples/ControlCatalog/MainWindow.xaml +++ b/samples/ControlCatalog/MainWindow.xaml @@ -1,6 +1,6 @@  + xmlns:local="clr-namespace:ControlCatalog"> \ No newline at end of file diff --git a/src/Avalonia.Base/Platform/IAssetLoader.cs b/src/Avalonia.Base/Platform/IAssetLoader.cs index eae8db5a14..32008ffd07 100644 --- a/src/Avalonia.Base/Platform/IAssetLoader.cs +++ b/src/Avalonia.Base/Platform/IAssetLoader.cs @@ -43,5 +43,7 @@ namespace Avalonia.Platform /// The resource was not found. /// Stream Open(Uri uri, Uri baseUri = null); + + Tuple OpenWithAssembly(Uri uri, Uri baseUri = null); } } diff --git a/src/Avalonia.DesignerSupport/DesignWindowLoader.cs b/src/Avalonia.DesignerSupport/DesignWindowLoader.cs index 9ad2a216b4..d9cac47bf3 100644 --- a/src/Avalonia.DesignerSupport/DesignWindowLoader.cs +++ b/src/Avalonia.DesignerSupport/DesignWindowLoader.cs @@ -1,6 +1,7 @@ using System; using System.IO; using System.Linq; +using System.Reflection; using System.Text; using Avalonia.Controls; using Avalonia.Controls.Platform; @@ -30,7 +31,8 @@ namespace Avalonia.DesignerSupport new Uri("resm:Fake.xaml?assembly=" + Path.GetFileNameWithoutExtension(assemblyPath)); } - var loaded = loader.Load(stream, null, baseUri); + var localAsm = assemblyPath != null ? Assembly.LoadFile(assemblyPath) : null; + var loaded = loader.Load(stream, localAsm, null, baseUri); var styles = loaded as Styles; if (styles != null) { diff --git a/src/Avalonia.DesignerSupport/DesignerAssist.cs b/src/Avalonia.DesignerSupport/DesignerAssist.cs index 65c4c14d83..f6f704b838 100644 --- a/src/Avalonia.DesignerSupport/DesignerAssist.cs +++ b/src/Avalonia.DesignerSupport/DesignerAssist.cs @@ -24,7 +24,7 @@ namespace Avalonia.DesignerSupport var loader = new AvaloniaXamlLoader(); var baseLight = (IStyle)loader.Load( - new Uri("resm:Avalonia.Themes.Default.Accents.BaseLight.xaml?assembly=Avalonia.Themes.Default")); + new Uri("resm:Avalonia.Themes.Default.Accents.BaseLight.xaml?assembly=Avalonia.Themes.Default"), null); Styles.Add(baseLight); } } diff --git a/src/Markup/Avalonia.Markup.Xaml/Avalonia.Markup.Xaml.csproj b/src/Markup/Avalonia.Markup.Xaml/Avalonia.Markup.Xaml.csproj index 0ce2a1a992..62c23543fd 100644 --- a/src/Markup/Avalonia.Markup.Xaml/Avalonia.Markup.Xaml.csproj +++ b/src/Markup/Avalonia.Markup.Xaml/Avalonia.Markup.Xaml.csproj @@ -30,7 +30,6 @@ Properties\SharedAssemblyInfo.cs - diff --git a/src/Markup/Avalonia.Markup.Xaml/AvaloniaXamlLoader.cs b/src/Markup/Avalonia.Markup.Xaml/AvaloniaXamlLoader.cs deleted file mode 100644 index 3142d954ff..0000000000 --- a/src/Markup/Avalonia.Markup.Xaml/AvaloniaXamlLoader.cs +++ /dev/null @@ -1,11 +0,0 @@ -namespace Avalonia.Markup.Xaml -{ - public class AvaloniaXamlLoader : AvaloniaXamlLoaderPortableXaml - { - public static object Parse(string xaml) - => new AvaloniaXamlLoader().Load(xaml); - - public static T Parse(string xaml) - => (T)Parse(xaml); - } -} \ No newline at end of file diff --git a/src/Markup/Avalonia.Markup.Xaml/AvaloniaXamlLoaderPortableXaml.cs b/src/Markup/Avalonia.Markup.Xaml/AvaloniaXamlLoaderPortableXaml.cs index de2a79c54e..e057aa3b53 100644 --- a/src/Markup/Avalonia.Markup.Xaml/AvaloniaXamlLoaderPortableXaml.cs +++ b/src/Markup/Avalonia.Markup.Xaml/AvaloniaXamlLoaderPortableXaml.cs @@ -17,7 +17,7 @@ namespace Avalonia.Markup.Xaml /// /// Loads XAML for a avalonia application. /// - public class AvaloniaXamlLoaderPortableXaml + public class AvaloniaXamlLoader { private readonly AvaloniaXamlSchemaContext _context = GetContext(); @@ -40,7 +40,7 @@ namespace Avalonia.Markup.Xaml /// /// Initializes a new instance of the class. /// - public AvaloniaXamlLoaderPortableXaml() + public AvaloniaXamlLoader() { } @@ -89,7 +89,7 @@ namespace Avalonia.Markup.Xaml initialize?.BeginInit(); try { - return Load(stream, rootInstance, uri); + return Load(stream, type.Assembly, rootInstance, uri); } finally { @@ -125,11 +125,12 @@ namespace Avalonia.Markup.Xaml "Could not create IAssetLoader : maybe Application.RegisterServices() wasn't called?"); } - using (var stream = assetLocator.Open(uri, baseUri)) + var asset = assetLocator.OpenWithAssembly(uri, baseUri); + using (var stream = asset.Item2) { try { - return Load(stream, rootInstance, uri); + return Load(stream, asset.Item1, rootInstance, uri); } catch (Exception e) { @@ -147,17 +148,18 @@ namespace Avalonia.Markup.Xaml /// Loads XAML from a string. /// /// The string containing the XAML. + /// Default assembly for clr-namespace: /// /// The optional instance into which the XAML should be loaded. /// /// The loaded object. - public object Load(string xaml, object rootInstance = null) + public object Load(string xaml, Assembly localAssembly, object rootInstance = null) { Contract.Requires(xaml != null); using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(xaml))) { - return Load(stream, rootInstance); + return Load(stream, localAssembly, rootInstance); } } @@ -165,17 +167,18 @@ namespace Avalonia.Markup.Xaml /// Loads XAML from a stream. /// /// The stream containing the XAML. + /// Default assembly for clr-namespace /// /// The optional instance into which the XAML should be loaded. /// /// The URI of the XAML /// The loaded object. - public object Load(Stream stream, object rootInstance = null, Uri uri = null) + public object Load(Stream stream, Assembly localAssembly, object rootInstance = null, Uri uri = null) { var readerSettings = new XamlXmlReaderSettings() { BaseUri = uri, - LocalAssembly = rootInstance?.GetType().GetTypeInfo().Assembly + LocalAssembly = localAssembly }; var reader = new XamlXmlReader(stream, _context, readerSettings); @@ -223,5 +226,11 @@ namespace Avalonia.Markup.Xaml yield return new Uri("resm:" + typeName + ".xaml?assembly=" + asm); yield return new Uri("resm:" + typeName + ".paml?assembly=" + asm); } + + public static object Parse(string xaml, Assembly localAssembly = null) + => new AvaloniaXamlLoader().Load(xaml, localAssembly); + + public static T Parse(string xaml, Assembly localAssembly) + => (T)Parse(xaml, localAssembly); } } \ No newline at end of file diff --git a/src/Shared/PlatformSupport/AssetLoader.cs b/src/Shared/PlatformSupport/AssetLoader.cs index 4287fd0b9e..eb9b04fe54 100644 --- a/src/Shared/PlatformSupport/AssetLoader.cs +++ b/src/Shared/PlatformSupport/AssetLoader.cs @@ -67,7 +67,20 @@ namespace Avalonia.Shared.PlatformSupport /// /// The resource was not found. /// - public Stream Open(Uri uri, Uri baseUri = null) + public Stream Open(Uri uri, Uri baseUri = null) => OpenWithAssembly(uri, baseUri).Item2; + + /// + /// Opens the resource with the requested URI. + /// + /// The URI. + /// + /// A base URI to use if is relative. + /// + /// An assembly (optional) and a stream containing the resource contents. + /// + /// The resource was not found. + /// + public Tuple OpenWithAssembly(Uri uri, Uri baseUri = null) { var asset = GetAsset(uri, baseUri); @@ -76,7 +89,7 @@ namespace Avalonia.Shared.PlatformSupport throw new FileNotFoundException($"The resource {uri} could not be found."); } - return asset.GetStream(); + return Tuple.Create(asset.Assembly, asset.GetStream()); } private IAssetDescriptor GetAsset(Uri uri, Uri baseUri) @@ -162,6 +175,7 @@ namespace Avalonia.Shared.PlatformSupport private interface IAssetDescriptor { Stream GetStream(); + Assembly Assembly { get; } } private class AssemblyResourceDescriptor : IAssetDescriptor @@ -179,6 +193,8 @@ namespace Avalonia.Shared.PlatformSupport { return _asm.GetManifestResourceStream(_name); } + + public Assembly Assembly => _asm; } private class AssemblyDescriptor diff --git a/tests/Avalonia.UnitTests/MockAssetLoader.cs b/tests/Avalonia.UnitTests/MockAssetLoader.cs index 5cff20c6a1..3cf7370f1f 100644 --- a/tests/Avalonia.UnitTests/MockAssetLoader.cs +++ b/tests/Avalonia.UnitTests/MockAssetLoader.cs @@ -27,6 +27,11 @@ namespace Avalonia.UnitTests { return new MemoryStream(Encoding.UTF8.GetBytes(_assets[uri])); } + + public Tuple OpenWithAssembly(Uri uri, Uri baseUri = null) + { + return Tuple.Create((Assembly) null, Open(uri, baseUri)); + } public void SetDefaultAssembly(Assembly asm) {