diff --git a/src/Markup/Avalonia.Markup.Xaml/Avalonia.Markup.Xaml.csproj b/src/Markup/Avalonia.Markup.Xaml/Avalonia.Markup.Xaml.csproj
index 9e9bd33046..01717af372 100644
--- a/src/Markup/Avalonia.Markup.Xaml/Avalonia.Markup.Xaml.csproj
+++ b/src/Markup/Avalonia.Markup.Xaml/Avalonia.Markup.Xaml.csproj
@@ -53,6 +53,8 @@
+
+
diff --git a/src/Markup/Avalonia.Markup.Xaml/AvaloniaXamlLoaderPortableXaml.cs b/src/Markup/Avalonia.Markup.Xaml/AvaloniaXamlLoaderPortableXaml.cs
index 84d65e20b3..f23ce9d8b3 100644
--- a/src/Markup/Avalonia.Markup.Xaml/AvaloniaXamlLoaderPortableXaml.cs
+++ b/src/Markup/Avalonia.Markup.Xaml/AvaloniaXamlLoaderPortableXaml.cs
@@ -2,7 +2,6 @@
// Licensed under the MIT license. See licence.md file in the project root for full license information.
using Avalonia.Controls;
-using Avalonia.Markup.Xaml.Context;
using Avalonia.Markup.Xaml.Data;
using Avalonia.Markup.Xaml.PortableXaml;
using Avalonia.Platform;
@@ -45,21 +44,6 @@ namespace Avalonia.Markup.Xaml
{
}
- ///
- /// Gets the URI of the XAML file currently being loaded.
- ///
- ///
- /// TODO: Making this internal for now as I'm not sure that this is the correct
- /// thing to do, but its needed by to get the URL of
- /// the currently loading XAML file, as we can't use the OmniXAML parsing context
- /// there. Maybe we need a way to inject OmniXAML context into the objects its
- /// constructing?
- ///
- [Obsolete]
- internal static Uri UriContext => s_uriStack.Count > 0 ? s_uriStack.Peek() : null;
-
- private static Stack s_uriStack = new Stack();
-
///
/// Loads the XAML into a Avalonia component.
///
@@ -176,47 +160,34 @@ namespace Avalonia.Markup.Xaml
/// The loaded object.
public object Load(Stream stream, object rootInstance = null, Uri uri = null)
{
- try
+ var readerSettings = new XamlXmlReaderSettings()
{
- if (uri != null)
- {
- s_uriStack.Push(uri);
- }
-
- var readerSettings = new XamlXmlReaderSettings();
-
- Type type = rootInstance?.GetType();
-
- if (type != null)
- {
- readerSettings.LocalAssembly = type.GetTypeInfo().Assembly;
- }
+ BaseUri = uri,
+ LocalAssembly = rootInstance?.GetType().GetTypeInfo().Assembly
+ };
- var reader = new XamlXmlReader(stream, _context, readerSettings);
+ var reader = new XamlXmlReader(stream, _context, readerSettings);
- object result = LoadFromReader(reader, rootInstance);
+ object result = LoadFromReader(reader, rootInstance, readerSettings);
- var topLevel = result as TopLevel;
+ var topLevel = result as TopLevel;
- if (topLevel != null)
- {
- DelayedBinding.ApplyBindings(topLevel);
- }
-
- return result;
- }
- finally
+ if (topLevel != null)
{
- if (uri != null)
- {
- s_uriStack.Pop();
- }
+ DelayedBinding.ApplyBindings(topLevel);
}
+
+ return result;
}
- internal static object LoadFromReader(XamlReader reader, object instance)
+ internal static object LoadFromReader(XamlReader reader,
+ object instance,
+ AvaloniaXamlContext context = null)
{
- var writer = AvaloniaXamlObjectWriter.Create(reader.SchemaContext, instance);
+ var writer = AvaloniaXamlObjectWriter.Create(
+ reader.SchemaContext,
+ instance,
+ context);
XamlServices.Transform(reader, writer);
diff --git a/src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/StyleIncludeExtension.cs b/src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/StyleIncludeExtension.cs
new file mode 100644
index 0000000000..1355ba0597
--- /dev/null
+++ b/src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/StyleIncludeExtension.cs
@@ -0,0 +1,29 @@
+// Copyright (c) The Avalonia Project. All rights reserved.
+// Licensed under the MIT license. See licence.md file in the project root for full license information.
+
+using Avalonia.Markup.Xaml.Styling;
+using Avalonia.Styling;
+using Portable.Xaml;
+using Portable.Xaml.ComponentModel;
+using Portable.Xaml.Markup;
+using System;
+
+namespace Avalonia.Markup.Xaml.MarkupExtensions
+{
+ [MarkupExtensionReturnType(typeof(IStyle))]
+ public class StyleIncludeExtension : MarkupExtension
+ {
+ public StyleIncludeExtension()
+ {
+ }
+
+ public override object ProvideValue(IServiceProvider serviceProvider)
+ {
+ var tdc = (ITypeDescriptorContext)serviceProvider;
+
+ return new StyleInclude(tdc.GetBaseUri()) { Source = Source };
+ }
+
+ public Uri Source { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/src/Markup/Avalonia.Markup.Xaml/PortableXaml/AvaloniaXamlContext.cs b/src/Markup/Avalonia.Markup.Xaml/PortableXaml/AvaloniaXamlContext.cs
new file mode 100644
index 0000000000..7196b841b0
--- /dev/null
+++ b/src/Markup/Avalonia.Markup.Xaml/PortableXaml/AvaloniaXamlContext.cs
@@ -0,0 +1,24 @@
+using Portable.Xaml;
+using System;
+using System.Reflection;
+
+namespace Avalonia.Markup.Xaml.PortableXaml
+{
+ public class AvaloniaXamlContext
+ {
+ internal AvaloniaXamlContext(Uri baseUri, Assembly localAssembly)
+ {
+ LocalAssembly = localAssembly;
+ BaseUri = baseUri;
+ }
+
+ public Assembly LocalAssembly { get; }
+
+ public Uri BaseUri { get; }
+
+ public static implicit operator AvaloniaXamlContext(XamlXmlReaderSettings sett)
+ {
+ return new AvaloniaXamlContext(sett.BaseUri, sett.LocalAssembly);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Markup/Avalonia.Markup.Xaml/PortableXaml/AvaloniaXamlObjectWriter.cs b/src/Markup/Avalonia.Markup.Xaml/PortableXaml/AvaloniaXamlObjectWriter.cs
index 53b3a8585a..c011be67cb 100644
--- a/src/Markup/Avalonia.Markup.Xaml/PortableXaml/AvaloniaXamlObjectWriter.cs
+++ b/src/Markup/Avalonia.Markup.Xaml/PortableXaml/AvaloniaXamlObjectWriter.cs
@@ -1,5 +1,6 @@
using Avalonia.Data;
using Portable.Xaml;
+using Portable.Xaml.ComponentModel;
using System.Collections.Generic;
using System.Linq;
@@ -7,15 +8,23 @@ namespace Avalonia.Markup.Xaml.PortableXaml
{
public class AvaloniaXamlObjectWriter : XamlObjectWriter
{
- public static AvaloniaXamlObjectWriter Create(XamlSchemaContext schemaContext, object instance)
+ public static AvaloniaXamlObjectWriter Create(
+ XamlSchemaContext schemaContext,
+ object instance,
+ AvaloniaXamlContext context)
{
- var writerSettings = new XamlObjectWriterSettings();
var nameScope = new AvaloniaNameScope { Instance = instance };
- writerSettings.ExternalNameScope = nameScope;
- writerSettings.RegisterNamesOnExternalNamescope = true;
- writerSettings.RootObjectInstance = instance;
- return new AvaloniaXamlObjectWriter(schemaContext, writerSettings, nameScope);
+ var writerSettings = new XamlObjectWriterSettings()
+ {
+ ExternalNameScope = nameScope,
+ RegisterNamesOnExternalNamescope = true,
+ RootObjectInstance = instance
+ };
+
+ return new AvaloniaXamlObjectWriter(schemaContext,
+ writerSettings.WithContext(context),
+ nameScope);
}
private readonly DelayedValuesHelper _delayedValuesHelper = new DelayedValuesHelper();
diff --git a/src/Markup/Avalonia.Markup.Xaml/PortableXaml/AvaloniaXamlSchemaContext.cs b/src/Markup/Avalonia.Markup.Xaml/PortableXaml/AvaloniaXamlSchemaContext.cs
index 85731abf37..1e7d78de72 100644
--- a/src/Markup/Avalonia.Markup.Xaml/PortableXaml/AvaloniaXamlSchemaContext.cs
+++ b/src/Markup/Avalonia.Markup.Xaml/PortableXaml/AvaloniaXamlSchemaContext.cs
@@ -1,12 +1,14 @@
using Avalonia.Data;
using Avalonia.Markup.Xaml.Context;
+using Avalonia.Markup.Xaml.Data;
+using Avalonia.Markup.Xaml.MarkupExtensions;
+using Avalonia.Markup.Xaml.Styling;
using Portable.Xaml;
using Portable.Xaml.ComponentModel;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
-using am = Avalonia.Metadata;
namespace Avalonia.Markup.Xaml.PortableXaml
{
@@ -19,7 +21,7 @@ namespace Avalonia.Markup.Xaml.PortableXaml
private AvaloniaXamlSchemaContext(IRuntimeTypeProvider typeProvider)
//better not set the references assemblies
- //TODO: check this on iOS
+ //TODO: check this on iOS
//: base(typeProvider.ReferencedAssemblies)
{
Contract.Requires(typeProvider != null);
@@ -150,16 +152,27 @@ namespace Avalonia.Markup.Xaml.PortableXaml
return result;
}
+ private static readonly Dictionary _wellKnownExtensionTypes = new Dictionary()
+ {
+ { typeof(Binding), typeof(BindingExtension) },
+ { typeof(StyleInclude), typeof(StyleIncludeExtension) },
+ };
+
private XamlType GetAvaloniaXamlType(Type type)
{
+ Type extType;
+
+ _wellKnownExtensionTypes.TryGetValue(type, out extType);
+
if (typeof(IBinding).GetTypeInfo().IsAssignableFrom(type.GetTypeInfo()))
{
- return BindingXamlType.Create(type, this);
+ return new BindingXamlType(extType ?? type, this);
}
- if (typeof(AvaloniaObject).GetTypeInfo().IsAssignableFrom(type.GetTypeInfo()))
+ if (extType != null ||
+ typeof(AvaloniaObject).GetTypeInfo().IsAssignableFrom(type.GetTypeInfo()))
{
- return new AvaloniaXamlType(type, this);
+ return new AvaloniaXamlType(extType ?? type, this);
}
return null;
diff --git a/src/Markup/Avalonia.Markup.Xaml/PortableXaml/AvaloniaXamlType.cs b/src/Markup/Avalonia.Markup.Xaml/PortableXaml/AvaloniaXamlType.cs
index 507631d053..53374711f6 100644
--- a/src/Markup/Avalonia.Markup.Xaml/PortableXaml/AvaloniaXamlType.cs
+++ b/src/Markup/Avalonia.Markup.Xaml/PortableXaml/AvaloniaXamlType.cs
@@ -1,7 +1,6 @@
using Avalonia.Controls;
using Avalonia.Data;
using Avalonia.Markup.Xaml.Data;
-using Avalonia.Markup.Xaml.MarkupExtensions;
using Avalonia.Metadata;
using Avalonia.Styling;
using Portable.Xaml;
@@ -48,24 +47,13 @@ namespace Avalonia.Markup.Xaml.PortableXaml
public class BindingXamlType : XamlType
{
- public static BindingXamlType Create(Type type, XamlSchemaContext schemaContext)
- {
- if (type == typeof(Binding))
- {
- //in xaml we need to use the extension
- type = typeof(BindingExtension);
- }
-
- return new BindingXamlType(type, schemaContext);
- }
-
private static List _notAssignable =
new List
{
typeof (IXmlSerializable)
};
- private BindingXamlType(Type underlyingType, XamlSchemaContext schemaContext) :
+ public BindingXamlType(Type underlyingType, XamlSchemaContext schemaContext) :
base(underlyingType, schemaContext)
{
}
@@ -194,7 +182,7 @@ namespace Avalonia.Markup.Xaml.PortableXaml
{
//can't make it work to assign TypeConverter to Setter.Value
//so we need it hard coded
- //TODO: try to assosiate TypeConverter with Setter.Value
+ //TODO: try to assosiate TypeConverter with Setter.Value
//and remove this lines
if (instance is Setter &&
Member.Name == nameof(Setter.Value) &&
diff --git a/src/Markup/Avalonia.Markup.Xaml/PortableXaml/TypeDescriptorExtensions.cs b/src/Markup/Avalonia.Markup.Xaml/PortableXaml/TypeDescriptorExtensions.cs
index 71330ddbbd..ebe1264856 100644
--- a/src/Markup/Avalonia.Markup.Xaml/PortableXaml/TypeDescriptorExtensions.cs
+++ b/src/Markup/Avalonia.Markup.Xaml/PortableXaml/TypeDescriptorExtensions.cs
@@ -1,7 +1,9 @@
-using System;
+using Avalonia.Markup.Xaml.PortableXaml;
using Portable.Xaml.Markup;
-using System.Linq;
+using System;
using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
namespace Portable.Xaml.ComponentModel
{
@@ -56,5 +58,41 @@ namespace Portable.Xaml.ComponentModel
return amb.GetAllAmbientValues(sc.GetXamlType(typeof(T))).OfType();
}
+
+ public static Uri GetBaseUri(this ITypeDescriptorContext ctx)
+ {
+ return ctx.GetWriterSettings()?.Context.BaseUri;
+ }
+
+ public static Assembly GetLocalAssembly(this ITypeDescriptorContext ctx)
+ {
+ return ctx.GetWriterSettings()?.Context.LocalAssembly;
+ }
+
+ public static AvaloniaXamlContext GetAvaloniaXamlContext(this ITypeDescriptorContext ctx)
+ {
+ return ctx.GetWriterSettings()?.Context;
+ }
+
+ public static XamlObjectWriterSettings WithContext(this XamlObjectWriterSettings settings, AvaloniaXamlContext context)
+ {
+ return new AvaloniaXamlObjectWriterSettings(settings, context);
+ }
+
+ private static AvaloniaXamlObjectWriterSettings GetWriterSettings(this ITypeDescriptorContext ctx)
+ {
+ return ctx.GetService().GetParentSettings() as AvaloniaXamlObjectWriterSettings;
+ }
+
+ private class AvaloniaXamlObjectWriterSettings : XamlObjectWriterSettings
+ {
+ public AvaloniaXamlObjectWriterSettings(XamlObjectWriterSettings settings, AvaloniaXamlContext context)
+ : base(settings)
+ {
+ Context = context;
+ }
+
+ public AvaloniaXamlContext Context { get; }
+ }
}
}
\ No newline at end of file
diff --git a/src/Markup/Avalonia.Markup.Xaml/Styling/StyleInclude.cs b/src/Markup/Avalonia.Markup.Xaml/Styling/StyleInclude.cs
index c6c69973cc..04bf28f1ee 100644
--- a/src/Markup/Avalonia.Markup.Xaml/Styling/StyleInclude.cs
+++ b/src/Markup/Avalonia.Markup.Xaml/Styling/StyleInclude.cs
@@ -1,8 +1,8 @@
// Copyright (c) The Avalonia Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
-using System;
using Avalonia.Styling;
+using System;
namespace Avalonia.Markup.Xaml.Styling
{
@@ -17,6 +17,9 @@ namespace Avalonia.Markup.Xaml.Styling
///
/// Initializes a new instance of the class.
///
+ ///
+#if OMNIXAML
+
public StyleInclude()
{
// StyleInclude will usually be loaded from XAML and its URI can be relative to the
@@ -25,6 +28,15 @@ namespace Avalonia.Markup.Xaml.Styling
_baseUri = AvaloniaXamlLoader.UriContext;
}
+#else
+
+ public StyleInclude(Uri baseUri)
+ {
+ _baseUri = baseUri;
+ }
+
+#endif
+
///
/// Gets or sets the source URL.
///
@@ -68,4 +80,4 @@ namespace Avalonia.Markup.Xaml.Styling
return Loaded.FindResource(name);
}
}
-}
+}
\ No newline at end of file