committed by
GitHub
134 changed files with 3486 additions and 2682 deletions
@ -0,0 +1,15 @@ |
|||
// 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; |
|||
|
|||
namespace Avalonia.Metadata |
|||
{ |
|||
/// <summary>
|
|||
/// Defines the ambient class/property
|
|||
/// </summary>
|
|||
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property, Inherited = true)] |
|||
public class AmbientAttribute : Attribute |
|||
{ |
|||
} |
|||
} |
|||
@ -0,0 +1,15 @@ |
|||
// 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; |
|||
|
|||
namespace Avalonia.Metadata |
|||
{ |
|||
/// <summary>
|
|||
/// Defines the property that contains the object's content in markup.
|
|||
/// </summary>
|
|||
[AttributeUsage(AttributeTargets.Property)] |
|||
public class TemplateContentAttribute : Attribute |
|||
{ |
|||
} |
|||
} |
|||
@ -0,0 +1,90 @@ |
|||
using System; |
|||
using System.Collections; |
|||
using System.Collections.Generic; |
|||
|
|||
namespace Avalonia.Styling |
|||
{ |
|||
/// <summary>
|
|||
/// Holds resources for a <see cref="Style"/>.
|
|||
/// </summary>
|
|||
public class StyleResources : IDictionary<string, object>, IDictionary |
|||
{ |
|||
private Dictionary<string, object> _inner = new Dictionary<string, object>(); |
|||
|
|||
public object this[string key] |
|||
{ |
|||
get { return _inner[key]; } |
|||
set { _inner[key] = value; } |
|||
} |
|||
|
|||
public int Count => _inner.Count; |
|||
|
|||
ICollection<string> IDictionary<string, object>.Keys => _inner.Keys; |
|||
|
|||
ICollection<object> IDictionary<string, object>.Values => _inner.Values; |
|||
|
|||
bool ICollection<KeyValuePair<string, object>>.IsReadOnly => false; |
|||
|
|||
object IDictionary.this[object key] |
|||
{ |
|||
get { return ((IDictionary)_inner)[key]; } |
|||
set { ((IDictionary)_inner)[key] = value; } |
|||
} |
|||
|
|||
ICollection IDictionary.Keys => _inner.Keys; |
|||
|
|||
ICollection IDictionary.Values => _inner.Values; |
|||
|
|||
bool ICollection.IsSynchronized => false; |
|||
|
|||
object ICollection.SyncRoot => ((IDictionary)_inner).SyncRoot; |
|||
|
|||
bool IDictionary.IsFixedSize => false; |
|||
|
|||
bool IDictionary.IsReadOnly => false; |
|||
|
|||
public void Add(string key, object value) => _inner.Add(key, value); |
|||
|
|||
public void Clear() => _inner.Clear(); |
|||
|
|||
public bool ContainsKey(string key) => _inner.ContainsKey(key); |
|||
|
|||
public bool Remove(string key) => _inner.Remove(key); |
|||
|
|||
public IEnumerator<KeyValuePair<string, object>> GetEnumerator() => _inner.GetEnumerator(); |
|||
|
|||
public bool TryGetValue(string key, out object value) => _inner.TryGetValue(key, out value); |
|||
|
|||
bool ICollection<KeyValuePair<string, object>>.Contains(KeyValuePair<string, object> item) |
|||
{ |
|||
return ((IDictionary<string, object>)_inner).Contains(item); |
|||
} |
|||
|
|||
void ICollection<KeyValuePair<string, object>>.Add(KeyValuePair<string, object> item) |
|||
{ |
|||
((IDictionary<string, object>)_inner).Add(item); |
|||
} |
|||
|
|||
void ICollection<KeyValuePair<string, object>>.CopyTo(KeyValuePair<string, object>[] array, int arrayIndex) |
|||
{ |
|||
((IDictionary<string, object>)_inner).CopyTo(array, arrayIndex); |
|||
} |
|||
|
|||
bool ICollection<KeyValuePair<string, object>>.Remove(KeyValuePair<string, object> item) |
|||
{ |
|||
return ((IDictionary<string, object>)_inner).Remove(item); |
|||
} |
|||
|
|||
void ICollection.CopyTo(Array array, int index) => ((IDictionary)_inner).CopyTo(array, index); |
|||
|
|||
IEnumerator IEnumerable.GetEnumerator() => _inner.GetEnumerator(); |
|||
|
|||
IDictionaryEnumerator IDictionary.GetEnumerator() => ((IDictionary)_inner).GetEnumerator(); |
|||
|
|||
void IDictionary.Add(object key, object value) => ((IDictionary)_inner).Add(key, value); |
|||
|
|||
bool IDictionary.Contains(object key) => ((IDictionary)_inner).Contains(key); |
|||
|
|||
void IDictionary.Remove(object key) => ((IDictionary)_inner).Remove(key); |
|||
} |
|||
} |
|||
@ -1,225 +1,11 @@ |
|||
// 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 System.Collections.Generic; |
|||
using System.IO; |
|||
using System.Reflection; |
|||
using System.Text; |
|||
using OmniXaml; |
|||
using Avalonia.Platform; |
|||
using Avalonia.Markup.Xaml.Context; |
|||
using Avalonia.Markup.Xaml.Styling; |
|||
using OmniXaml.ObjectAssembler; |
|||
using Avalonia.Controls; |
|||
using Avalonia.Markup.Xaml.Data; |
|||
|
|||
namespace Avalonia.Markup.Xaml |
|||
namespace Avalonia.Markup.Xaml |
|||
{ |
|||
/// <summary>
|
|||
/// Loads XAML for a avalonia application.
|
|||
/// </summary>
|
|||
public class AvaloniaXamlLoader : XmlLoader |
|||
public class AvaloniaXamlLoader : AvaloniaXamlLoaderPortableXaml |
|||
{ |
|||
private static AvaloniaParserFactory s_parserFactory; |
|||
private static IInstanceLifeCycleListener s_lifeCycleListener = new AvaloniaLifeCycleListener(); |
|||
private static Stack<Uri> s_uriStack = new Stack<Uri>(); |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="AvaloniaXamlLoader"/> class.
|
|||
/// </summary>
|
|||
public AvaloniaXamlLoader() |
|||
: this(GetParserFactory()) |
|||
{ |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="AvaloniaXamlLoader"/> class.
|
|||
/// </summary>
|
|||
/// <param name="xamlParserFactory">The parser factory to use.</param>
|
|||
public AvaloniaXamlLoader(IParserFactory xamlParserFactory) |
|||
: base(xamlParserFactory) |
|||
{ |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the URI of the XAML file currently being loaded.
|
|||
/// </summary>
|
|||
/// <remarks>
|
|||
/// TODO: Making this internal for now as I'm not sure that this is the correct
|
|||
/// thing to do, but its needed by <see cref="StyleInclude"/> 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?
|
|||
/// </remarks>
|
|||
internal static Uri UriContext => s_uriStack.Count > 0 ? s_uriStack.Peek() : null; |
|||
|
|||
/// <summary>
|
|||
/// Loads the XAML into a Avalonia component.
|
|||
/// </summary>
|
|||
/// <param name="obj">The object to load the XAML into.</param>
|
|||
public static void Load(object obj) |
|||
{ |
|||
Contract.Requires<ArgumentNullException>(obj != null); |
|||
|
|||
var loader = new AvaloniaXamlLoader(); |
|||
loader.Load(obj.GetType(), obj); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Loads the XAML for a type.
|
|||
/// </summary>
|
|||
/// <param name="type">The type.</param>
|
|||
/// <param name="rootInstance">
|
|||
/// The optional instance into which the XAML should be loaded.
|
|||
/// </param>
|
|||
/// <returns>The loaded object.</returns>
|
|||
public object Load(Type type, object rootInstance = null) |
|||
{ |
|||
Contract.Requires<ArgumentNullException>(type != null); |
|||
|
|||
// HACK: Currently Visual Studio is forcing us to change the extension of xaml files
|
|||
// in certain situations, so we try to load .xaml and if that's not found we try .xaml.
|
|||
// Ideally we'd be able to use .xaml everywhere
|
|||
var assetLocator = AvaloniaLocator.Current.GetService<IAssetLoader>(); |
|||
|
|||
if (assetLocator == null) |
|||
{ |
|||
throw new InvalidOperationException( |
|||
"Could not create IAssetLoader : maybe Application.RegisterServices() wasn't called?"); |
|||
} |
|||
|
|||
foreach (var uri in GetUrisFor(type)) |
|||
{ |
|||
if (assetLocator.Exists(uri)) |
|||
{ |
|||
using (var stream = assetLocator.Open(uri)) |
|||
{ |
|||
var initialize = rootInstance as ISupportInitialize; |
|||
initialize?.BeginInit(); |
|||
return Load(stream, rootInstance, uri); |
|||
} |
|||
} |
|||
} |
|||
|
|||
throw new FileNotFoundException("Unable to find view for " + type.FullName); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Loads XAML from a URI.
|
|||
/// </summary>
|
|||
/// <param name="uri">The URI of the XAML file.</param>
|
|||
/// <param name="baseUri">
|
|||
/// A base URI to use if <paramref name="uri"/> is relative.
|
|||
/// </param>
|
|||
/// <param name="rootInstance">
|
|||
/// The optional instance into which the XAML should be loaded.
|
|||
/// </param>
|
|||
/// <returns>The loaded object.</returns>
|
|||
public object Load(Uri uri, Uri baseUri = null, object rootInstance = null) |
|||
{ |
|||
Contract.Requires<ArgumentNullException>(uri != null); |
|||
|
|||
var assetLocator = AvaloniaLocator.Current.GetService<IAssetLoader>(); |
|||
|
|||
if (assetLocator == null) |
|||
{ |
|||
throw new InvalidOperationException( |
|||
"Could not create IAssetLoader : maybe Application.RegisterServices() wasn't called?"); |
|||
} |
|||
|
|||
using (var stream = assetLocator.Open(uri, baseUri)) |
|||
{ |
|||
return Load(stream, rootInstance, uri); |
|||
} |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Loads XAML from a string.
|
|||
/// </summary>
|
|||
/// <param name="xaml">The string containing the XAML.</param>
|
|||
/// <param name="rootInstance">
|
|||
/// The optional instance into which the XAML should be loaded.
|
|||
/// </param>
|
|||
/// <returns>The loaded object.</returns>
|
|||
public object Load(string xaml, object rootInstance = null) |
|||
{ |
|||
Contract.Requires<ArgumentNullException>(xaml != null); |
|||
|
|||
using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(xaml))) |
|||
{ |
|||
return Load(stream, rootInstance); |
|||
} |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Loads XAML from a stream.
|
|||
/// </summary>
|
|||
/// <param name="stream">The stream containing the XAML.</param>
|
|||
/// <param name="rootInstance">
|
|||
/// The optional instance into which the XAML should be loaded.
|
|||
/// </param>
|
|||
/// <param name="uri">The URI of the XAML</param>
|
|||
/// <returns>The loaded object.</returns>
|
|||
public object Load(Stream stream, object rootInstance = null, Uri uri = null) |
|||
{ |
|||
try |
|||
{ |
|||
if (uri != null) |
|||
{ |
|||
s_uriStack.Push(uri); |
|||
} |
|||
|
|||
var result = base.Load(stream, new Settings |
|||
{ |
|||
RootInstance = rootInstance, |
|||
InstanceLifeCycleListener = s_lifeCycleListener, |
|||
ParsingContext = new Dictionary<string, object> |
|||
{ |
|||
{ "Uri", uri } |
|||
} |
|||
}); |
|||
|
|||
var topLevel = result as TopLevel; |
|||
|
|||
if (topLevel != null) |
|||
{ |
|||
DelayedBinding.ApplyBindings(topLevel); |
|||
} |
|||
|
|||
return result; |
|||
} |
|||
finally |
|||
{ |
|||
if (uri != null) |
|||
{ |
|||
s_uriStack.Pop(); |
|||
} |
|||
} |
|||
} |
|||
|
|||
private static AvaloniaParserFactory GetParserFactory() |
|||
{ |
|||
if (s_parserFactory == null) |
|||
{ |
|||
s_parserFactory = new AvaloniaParserFactory(); |
|||
} |
|||
|
|||
return s_parserFactory; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the URI for a type.
|
|||
/// </summary>
|
|||
/// <param name="type">The type.</param>
|
|||
/// <returns>The URI.</returns>
|
|||
private static IEnumerable<Uri> GetUrisFor(Type type) |
|||
{ |
|||
var asm = type.GetTypeInfo().Assembly.GetName().Name; |
|||
var typeName = type.FullName; |
|||
yield return new Uri("resm:" + typeName + ".xaml?assembly=" + asm); |
|||
yield return new Uri("resm:" + typeName + ".paml?assembly=" + asm); |
|||
public static object Parse(string xaml) |
|||
=> new AvaloniaXamlLoader().Load(xaml); |
|||
|
|||
} |
|||
public static T Parse<T>(string xaml) |
|||
=> (T)Parse(xaml); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,215 @@ |
|||
// 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.Controls; |
|||
using Avalonia.Markup.Xaml.Data; |
|||
using Avalonia.Markup.Xaml.PortableXaml; |
|||
using Avalonia.Platform; |
|||
using Portable.Xaml; |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.IO; |
|||
using System.Reflection; |
|||
using System.Text; |
|||
|
|||
namespace Avalonia.Markup.Xaml |
|||
{ |
|||
/// <summary>
|
|||
/// Loads XAML for a avalonia application.
|
|||
/// </summary>
|
|||
public class AvaloniaXamlLoaderPortableXaml |
|||
{ |
|||
private readonly AvaloniaXamlSchemaContext _context = GetContext(); |
|||
|
|||
private static AvaloniaXamlSchemaContext GetContext() |
|||
{ |
|||
var result = AvaloniaLocator.Current.GetService<AvaloniaXamlSchemaContext>(); |
|||
|
|||
if (result == null) |
|||
{ |
|||
result = AvaloniaXamlSchemaContext.Create(); |
|||
|
|||
AvaloniaLocator.CurrentMutable |
|||
.Bind<AvaloniaXamlSchemaContext>() |
|||
.ToConstant(result); |
|||
} |
|||
|
|||
return result; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="AvaloniaXamlLoader"/> class.
|
|||
/// </summary>
|
|||
public AvaloniaXamlLoaderPortableXaml() |
|||
{ |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Loads the XAML into a Avalonia component.
|
|||
/// </summary>
|
|||
/// <param name="obj">The object to load the XAML into.</param>
|
|||
public static void Load(object obj) |
|||
{ |
|||
Contract.Requires<ArgumentNullException>(obj != null); |
|||
|
|||
var loader = new AvaloniaXamlLoader(); |
|||
loader.Load(obj.GetType(), obj); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Loads the XAML for a type.
|
|||
/// </summary>
|
|||
/// <param name="type">The type.</param>
|
|||
/// <param name="rootInstance">
|
|||
/// The optional instance into which the XAML should be loaded.
|
|||
/// </param>
|
|||
/// <returns>The loaded object.</returns>
|
|||
public object Load(Type type, object rootInstance = null) |
|||
{ |
|||
Contract.Requires<ArgumentNullException>(type != null); |
|||
|
|||
// HACK: Currently Visual Studio is forcing us to change the extension of xaml files
|
|||
// in certain situations, so we try to load .xaml and if that's not found we try .xaml.
|
|||
// Ideally we'd be able to use .xaml everywhere
|
|||
var assetLocator = AvaloniaLocator.Current.GetService<IAssetLoader>(); |
|||
|
|||
if (assetLocator == null) |
|||
{ |
|||
throw new InvalidOperationException( |
|||
"Could not create IAssetLoader : maybe Application.RegisterServices() wasn't called?"); |
|||
} |
|||
|
|||
foreach (var uri in GetUrisFor(type)) |
|||
{ |
|||
if (assetLocator.Exists(uri)) |
|||
{ |
|||
using (var stream = assetLocator.Open(uri)) |
|||
{ |
|||
var initialize = rootInstance as ISupportInitialize; |
|||
initialize?.BeginInit(); |
|||
try |
|||
{ |
|||
return Load(stream, rootInstance, uri); |
|||
} |
|||
finally |
|||
{ |
|||
initialize?.EndInit(); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
throw new FileNotFoundException("Unable to find view for " + type.FullName); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Loads XAML from a URI.
|
|||
/// </summary>
|
|||
/// <param name="uri">The URI of the XAML file.</param>
|
|||
/// <param name="baseUri">
|
|||
/// A base URI to use if <paramref name="uri"/> is relative.
|
|||
/// </param>
|
|||
/// <param name="rootInstance">
|
|||
/// The optional instance into which the XAML should be loaded.
|
|||
/// </param>
|
|||
/// <returns>The loaded object.</returns>
|
|||
public object Load(Uri uri, Uri baseUri = null, object rootInstance = null) |
|||
{ |
|||
Contract.Requires<ArgumentNullException>(uri != null); |
|||
|
|||
var assetLocator = AvaloniaLocator.Current.GetService<IAssetLoader>(); |
|||
|
|||
if (assetLocator == null) |
|||
{ |
|||
throw new InvalidOperationException( |
|||
"Could not create IAssetLoader : maybe Application.RegisterServices() wasn't called?"); |
|||
} |
|||
|
|||
using (var stream = assetLocator.Open(uri, baseUri)) |
|||
{ |
|||
return Load(stream, rootInstance, uri); |
|||
} |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Loads XAML from a string.
|
|||
/// </summary>
|
|||
/// <param name="xaml">The string containing the XAML.</param>
|
|||
/// <param name="rootInstance">
|
|||
/// The optional instance into which the XAML should be loaded.
|
|||
/// </param>
|
|||
/// <returns>The loaded object.</returns>
|
|||
public object Load(string xaml, object rootInstance = null) |
|||
{ |
|||
Contract.Requires<ArgumentNullException>(xaml != null); |
|||
|
|||
using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(xaml))) |
|||
{ |
|||
return Load(stream, rootInstance); |
|||
} |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Loads XAML from a stream.
|
|||
/// </summary>
|
|||
/// <param name="stream">The stream containing the XAML.</param>
|
|||
/// <param name="rootInstance">
|
|||
/// The optional instance into which the XAML should be loaded.
|
|||
/// </param>
|
|||
/// <param name="uri">The URI of the XAML</param>
|
|||
/// <returns>The loaded object.</returns>
|
|||
public object Load(Stream stream, object rootInstance = null, Uri uri = null) |
|||
{ |
|||
var readerSettings = new XamlXmlReaderSettings() |
|||
{ |
|||
BaseUri = uri, |
|||
LocalAssembly = rootInstance?.GetType().GetTypeInfo().Assembly |
|||
}; |
|||
|
|||
var reader = new XamlXmlReader(stream, _context, readerSettings); |
|||
|
|||
object result = LoadFromReader( |
|||
reader, |
|||
AvaloniaXamlContext.For(readerSettings, rootInstance)); |
|||
|
|||
var topLevel = result as TopLevel; |
|||
|
|||
if (topLevel != null) |
|||
{ |
|||
DelayedBinding.ApplyBindings(topLevel); |
|||
} |
|||
|
|||
return result; |
|||
} |
|||
|
|||
internal static object LoadFromReader(XamlReader reader, AvaloniaXamlContext context = null) |
|||
{ |
|||
var writer = AvaloniaXamlObjectWriter.Create( |
|||
reader.SchemaContext, |
|||
context); |
|||
|
|||
XamlServices.Transform(reader, writer); |
|||
|
|||
return writer.Result; |
|||
} |
|||
|
|||
internal static object LoadFromReader(XamlReader reader) |
|||
{ |
|||
//return XamlServices.Load(reader);
|
|||
return LoadFromReader(reader, null); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the URI for a type.
|
|||
/// </summary>
|
|||
/// <param name="type">The type.</param>
|
|||
/// <returns>The URI.</returns>
|
|||
private static IEnumerable<Uri> GetUrisFor(Type type) |
|||
{ |
|||
var asm = type.GetTypeInfo().Assembly.GetName().Name; |
|||
var typeName = type.FullName; |
|||
yield return new Uri("resm:" + typeName + ".xaml?assembly=" + asm); |
|||
yield return new Uri("resm:" + typeName + ".paml?assembly=" + asm); |
|||
} |
|||
} |
|||
} |
|||
@ -1,33 +0,0 @@ |
|||
// 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.Data; |
|||
using OmniXaml; |
|||
using OmniXaml.Typing; |
|||
using System.Reflection; |
|||
|
|||
namespace Avalonia.Markup.Xaml.Context |
|||
{ |
|||
public class AvaloniaAttachableXamlMember : AttachableMember |
|||
{ |
|||
public AvaloniaAttachableXamlMember(string name, |
|||
XamlType owner, |
|||
MethodInfo getter, |
|||
MethodInfo setter, |
|||
ITypeRepository xamlTypeRepository, |
|||
ITypeFeatureProvider featureProvider) |
|||
: base(name, getter, setter, xamlTypeRepository, featureProvider) |
|||
{ |
|||
} |
|||
|
|||
public override string ToString() |
|||
{ |
|||
return "Avalonia Attachable XAML Member " + base.ToString(); |
|||
} |
|||
|
|||
protected override IMemberValuePlugin LookupXamlMemberValueConnector() |
|||
{ |
|||
return new AvaloniaMemberValuePlugin(this); |
|||
} |
|||
} |
|||
} |
|||
@ -1,58 +0,0 @@ |
|||
// 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 System.Collections; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Reflection; |
|||
using Glass; |
|||
using OmniXaml; |
|||
using OmniXaml.Builder; |
|||
using Avalonia.Metadata; |
|||
|
|||
namespace Avalonia.Markup.Xaml.Context |
|||
{ |
|||
public class AvaloniaContentPropertyProvider : IContentPropertyProvider |
|||
{ |
|||
private readonly Dictionary<Type, string> _values = new Dictionary<Type, string>(); |
|||
|
|||
public string GetContentPropertyName(Type type) |
|||
{ |
|||
string result; |
|||
|
|||
if (!_values.TryGetValue(type, out result)) |
|||
{ |
|||
result = LookupContentProperty(type); |
|||
_values[type] = result; |
|||
} |
|||
|
|||
return result; |
|||
} |
|||
|
|||
private string LookupContentProperty(Type type) |
|||
{ |
|||
var result = (from member in type.GetRuntimeProperties() |
|||
let att = member.GetCustomAttribute<ContentAttribute>() |
|||
where att != null |
|||
select member).FirstOrDefault(); |
|||
|
|||
return result?.Name; |
|||
} |
|||
|
|||
void IAdd<ContentPropertyDefinition>.Add(ContentPropertyDefinition item) |
|||
{ |
|||
throw new NotImplementedException(); |
|||
} |
|||
|
|||
IEnumerator IEnumerable.GetEnumerator() |
|||
{ |
|||
throw new NotImplementedException(); |
|||
} |
|||
|
|||
IEnumerator<ContentPropertyDefinition> IEnumerable<ContentPropertyDefinition>.GetEnumerator() |
|||
{ |
|||
throw new NotImplementedException(); |
|||
} |
|||
} |
|||
} |
|||
@ -1,31 +0,0 @@ |
|||
// 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 OmniXaml; |
|||
|
|||
namespace Avalonia.Markup.Xaml.Context |
|||
{ |
|||
public class AvaloniaLifeCycleListener : IInstanceLifeCycleListener |
|||
{ |
|||
public void OnAfterProperties(object instance) |
|||
{ |
|||
} |
|||
|
|||
public void OnAssociatedToParent(object instance) |
|||
{ |
|||
} |
|||
|
|||
public void OnBegin(object instance) |
|||
{ |
|||
var isi = instance as ISupportInitialize; |
|||
isi?.BeginInit(); |
|||
} |
|||
|
|||
public void OnEnd(object instance) |
|||
{ |
|||
var isi = instance as ISupportInitialize; |
|||
isi?.EndInit(); |
|||
} |
|||
} |
|||
} |
|||
@ -1,25 +0,0 @@ |
|||
// 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 OmniXaml.TypeConversion; |
|||
using OmniXaml.Typing; |
|||
|
|||
namespace Avalonia.Markup.Xaml.Context |
|||
{ |
|||
public class AvaloniaMemberValuePlugin : MemberValuePlugin |
|||
{ |
|||
private readonly MutableMember _xamlMember; |
|||
|
|||
public AvaloniaMemberValuePlugin(MutableMember xamlMember) |
|||
: base(xamlMember) |
|||
{ |
|||
_xamlMember = xamlMember; |
|||
} |
|||
|
|||
public override void SetValue(object instance, object value, IValueContext valueContext) |
|||
{ |
|||
PropertyAccessor.SetValue(instance, _xamlMember, value, valueContext); |
|||
} |
|||
} |
|||
} |
|||
@ -1,181 +0,0 @@ |
|||
// 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 System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Reflection; |
|||
using OmniXaml.Builder; |
|||
using OmniXaml.Typing; |
|||
using Avalonia.Controls; |
|||
using Avalonia.Markup.Xaml.Templates; |
|||
using Avalonia.Media; |
|||
using Avalonia.Metadata; |
|||
using Avalonia.Platform; |
|||
using Avalonia.Styling; |
|||
using Glass.Core; |
|||
|
|||
namespace Avalonia.Markup.Xaml.Context |
|||
{ |
|||
public class AvaloniaNamespaceRegistry : INamespaceRegistry |
|||
{ |
|||
private const string ClrNamespace = "clr-namespace:"; |
|||
private const string AvaloniaNs = "https://github.com/avaloniaui"; |
|||
|
|||
private static readonly IEnumerable<Assembly> ForcedAssemblies = new[] |
|||
{ |
|||
typeof(AvaloniaObject).GetTypeInfo().Assembly, |
|||
typeof(Control).GetTypeInfo().Assembly, |
|||
typeof(Style).GetTypeInfo().Assembly, |
|||
typeof(DataTemplate).GetTypeInfo().Assembly, |
|||
typeof(SolidColorBrush).GetTypeInfo().Assembly, |
|||
typeof(IValueConverter).GetTypeInfo().Assembly, |
|||
}; |
|||
|
|||
private List<ClrNamespace> _clrNamespaces = new List<ClrNamespace>(); |
|||
private List<XamlNamespace> _namespaces = new List<XamlNamespace>(); |
|||
private Dictionary<string, string> _prefixes = new Dictionary<string, string>(); |
|||
private List<Assembly> _scanned = new List<Assembly>(); |
|||
|
|||
public AvaloniaNamespaceRegistry() |
|||
{ |
|||
ScanAssemblies(ForcedAssemblies); |
|||
ScanNewAssemblies(); |
|||
RegisterPrefix(new PrefixRegistration(string.Empty, AvaloniaNs)); |
|||
} |
|||
|
|||
public IEnumerable<PrefixRegistration> RegisteredPrefixes => |
|||
_prefixes.Select(x => new PrefixRegistration(x.Key, x.Value)); |
|||
|
|||
public void AddNamespace(XamlNamespace xamlNamespace) |
|||
{ |
|||
_namespaces.Add(xamlNamespace); |
|||
} |
|||
|
|||
public Namespace GetNamespace(string name) |
|||
{ |
|||
Namespace result; |
|||
|
|||
if (!IsClrNamespace(name)) |
|||
{ |
|||
ScanNewAssemblies(); |
|||
result = _namespaces.FirstOrDefault(x => x.Name == name); |
|||
|
|||
if (result == null) |
|||
{ |
|||
result = _namespaces.FirstOrDefault(x => x.Name == name); |
|||
} |
|||
} |
|||
else |
|||
{ |
|||
var nsAndAssembly = ParseClrNameSpace(name); |
|||
|
|||
result = _clrNamespaces.FirstOrDefault(x => |
|||
x.Name == nsAndAssembly.Item1 && |
|||
x.Assembly.GetName().Name == nsAndAssembly.Item2); |
|||
|
|||
if (result == null) |
|||
{ |
|||
var clr = CreateClrNamespace(name); |
|||
_clrNamespaces.Add(clr); |
|||
result = clr; |
|||
} |
|||
} |
|||
|
|||
return result; |
|||
} |
|||
|
|||
public Namespace GetNamespaceByPrefix(string prefix) |
|||
{ |
|||
string uri; |
|||
|
|||
if (_prefixes.TryGetValue(prefix, out uri)) |
|||
{ |
|||
return GetNamespace(uri); |
|||
} |
|||
|
|||
return null; |
|||
} |
|||
|
|||
public void RegisterPrefix(PrefixRegistration prefixRegistration) |
|||
{ |
|||
_prefixes[prefixRegistration.Prefix] = prefixRegistration.Ns; |
|||
} |
|||
|
|||
private static bool IsClrNamespace(string ns) |
|||
{ |
|||
return ns.StartsWith(ClrNamespace); |
|||
} |
|||
|
|||
private static ClrNamespace CreateClrNamespace(string formattedClrString) |
|||
{ |
|||
var nsAndAssembly = ParseClrNameSpace(formattedClrString); |
|||
var assembly = GetAssembly(nsAndAssembly.Item2); |
|||
|
|||
return new ClrNamespace(assembly, nsAndAssembly.Item1); |
|||
} |
|||
|
|||
private static Tuple<string, string> ParseClrNameSpace(string clrNamespace) |
|||
{ |
|||
var startOfNamespace = clrNamespace.IndexOf(":", StringComparison.Ordinal) + 1; |
|||
var endOfNamespace = clrNamespace.IndexOf(";", startOfNamespace, StringComparison.Ordinal); |
|||
|
|||
if (endOfNamespace < 0) |
|||
{ |
|||
endOfNamespace = clrNamespace.Length - startOfNamespace; |
|||
} |
|||
|
|||
var ns = clrNamespace.Substring(startOfNamespace, endOfNamespace - startOfNamespace); |
|||
|
|||
var remainingPartStart = startOfNamespace + ns.Length + 1; |
|||
var remainingPartLenght = clrNamespace.Length - remainingPartStart; |
|||
var assemblyPart = clrNamespace.Substring(remainingPartStart, remainingPartLenght); |
|||
|
|||
return Tuple.Create(ns, assemblyPart.Dicotomize('=').Item2); |
|||
} |
|||
|
|||
private static Assembly GetAssembly(string assemblyName) |
|||
{ |
|||
return Assembly.Load(new AssemblyName(assemblyName)); |
|||
} |
|||
|
|||
private void ScanAssemblies(IEnumerable<Assembly> assemblies) |
|||
{ |
|||
foreach (var assembly in assemblies) |
|||
{ |
|||
var namespaces = assembly.GetCustomAttributes<XmlnsDefinitionAttribute>() |
|||
.Select(x => new { x.XmlNamespace, x.ClrNamespace }) |
|||
.GroupBy(x => x.XmlNamespace); |
|||
|
|||
foreach (var nsa in namespaces) |
|||
{ |
|||
var xamlNamespace = _namespaces.FirstOrDefault(x => x.Name == nsa.Key); |
|||
|
|||
if (xamlNamespace == null) |
|||
{ |
|||
xamlNamespace = new XamlNamespace(nsa.Key); |
|||
_namespaces.Add(xamlNamespace); |
|||
} |
|||
|
|||
var clrNamespaces = nsa.Select(x => x.ClrNamespace); |
|||
xamlNamespace.Addresses.Add(new ConfiguredAssemblyWithNamespaces(assembly, clrNamespaces)); |
|||
} |
|||
|
|||
_scanned.Add(assembly); |
|||
} |
|||
} |
|||
|
|||
private void ScanNewAssemblies() |
|||
{ |
|||
IEnumerable<Assembly> assemblies = AvaloniaLocator.Current |
|||
.GetService<IRuntimePlatform>() |
|||
?.GetLoadedAssemblies(); |
|||
|
|||
if (assemblies != null) |
|||
{ |
|||
assemblies = assemblies.Except(_scanned); |
|||
ScanAssemblies(assemblies); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -1,79 +0,0 @@ |
|||
// 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 OmniXaml; |
|||
using OmniXaml.ObjectAssembler; |
|||
using OmniXaml.ObjectAssembler.Commands; |
|||
using OmniXaml.TypeConversion; |
|||
using Avalonia.Markup.Xaml.Templates; |
|||
using System.Collections.Generic; |
|||
using System.Collections.ObjectModel; |
|||
|
|||
namespace Avalonia.Markup.Xaml.Context |
|||
{ |
|||
public class AvaloniaObjectAssembler : IObjectAssembler |
|||
{ |
|||
private readonly TemplateHostingObjectAssembler objectAssembler; |
|||
private readonly ObjectAssembler assembler; |
|||
|
|||
public AvaloniaObjectAssembler( |
|||
IRuntimeTypeSource typeSource, |
|||
ITopDownValueContext topDownValueContext, |
|||
Settings settings = null) |
|||
{ |
|||
var mapping = new DeferredLoaderMapping(); |
|||
mapping.Map<Template>(x => x.Content, new TemplateLoader()); |
|||
mapping.Map<ControlTemplate>(x => x.Content, new TemplateLoader()); |
|||
mapping.Map<DataTemplate>(x => x.Content, new TemplateLoader()); |
|||
mapping.Map<FocusAdornerTemplate>(x => x.Content, new TemplateLoader()); |
|||
mapping.Map<TreeDataTemplate>(x => x.Content, new TemplateLoader()); |
|||
mapping.Map<ItemsPanelTemplate>(x => x.Content, new TemplateLoader()); |
|||
|
|||
var parsingDictionary = GetDictionary(settings); |
|||
var valueContext = new ValueContext(typeSource, topDownValueContext, parsingDictionary); |
|||
assembler = new ObjectAssembler(typeSource, valueContext, settings); |
|||
objectAssembler = new TemplateHostingObjectAssembler(assembler, mapping); |
|||
} |
|||
|
|||
|
|||
public object Result => objectAssembler.Result; |
|||
|
|||
public EventHandler<XamlSetValueEventArgs> XamlSetValueHandler { get; set; } |
|||
|
|||
public IRuntimeTypeSource TypeSource => assembler.TypeSource; |
|||
|
|||
public ITopDownValueContext TopDownValueContext => assembler.TopDownValueContext; |
|||
|
|||
public IInstanceLifeCycleListener LifecycleListener |
|||
{ |
|||
get { throw new NotImplementedException(); } |
|||
} |
|||
|
|||
public void Process(Instruction node) |
|||
{ |
|||
objectAssembler.Process(node); |
|||
} |
|||
|
|||
public void OverrideInstance(object instance) |
|||
{ |
|||
objectAssembler.OverrideInstance(instance); |
|||
} |
|||
|
|||
private static IReadOnlyDictionary<string, object> GetDictionary(Settings settings) |
|||
{ |
|||
IReadOnlyDictionary<string, object> dict; |
|||
|
|||
if (settings != null) |
|||
{ |
|||
dict = settings.ParsingContext; |
|||
} |
|||
else |
|||
{ |
|||
dict = new ReadOnlyDictionary<string, object>(new Dictionary<string, object>()); |
|||
} |
|||
|
|||
return dict; |
|||
} |
|||
} |
|||
} |
|||
@ -1,41 +0,0 @@ |
|||
// 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 OmniXaml; |
|||
using OmniXaml.ObjectAssembler; |
|||
using OmniXaml.Parsers.Parser; |
|||
using OmniXaml.Parsers.ProtoParser; |
|||
|
|||
namespace Avalonia.Markup.Xaml.Context |
|||
{ |
|||
public class AvaloniaParserFactory : IParserFactory |
|||
{ |
|||
private readonly IRuntimeTypeSource runtimeTypeSource; |
|||
|
|||
public AvaloniaParserFactory() |
|||
: this(new TypeFactory()) |
|||
{ |
|||
} |
|||
|
|||
public AvaloniaParserFactory(ITypeFactory typeFactory) |
|||
{ |
|||
runtimeTypeSource = new AvaloniaRuntimeTypeSource(typeFactory); |
|||
} |
|||
|
|||
public IParser Create(Settings settings) |
|||
{ |
|||
var xamlInstructionParser = new OrderAwareInstructionParser(new InstructionParser(runtimeTypeSource)); |
|||
|
|||
IObjectAssembler objectAssembler = new AvaloniaObjectAssembler( |
|||
runtimeTypeSource, |
|||
new TopDownValueContext(), |
|||
settings); |
|||
var phaseParserKit = new PhaseParserKit( |
|||
new ProtoInstructionParser(runtimeTypeSource), |
|||
xamlInstructionParser, |
|||
objectAssembler); |
|||
|
|||
return new XmlParser(phaseParserKit); |
|||
} |
|||
} |
|||
} |
|||
@ -1,91 +0,0 @@ |
|||
namespace Avalonia.Markup.Xaml.Context |
|||
{ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Reflection; |
|||
using Collections; |
|||
using Controls; |
|||
using Controls.Primitives; |
|||
using Controls.Templates; |
|||
using Converters; |
|||
using Data; |
|||
using Glass; |
|||
using Input; |
|||
using Media; |
|||
using Media.Imaging; |
|||
using Metadata; |
|||
using OmniXaml; |
|||
using OmniXaml.Builder; |
|||
using OmniXaml.TypeConversion; |
|||
using OmniXaml.Typing; |
|||
using Avalonia.Styling; |
|||
using Platform; |
|||
using Templates; |
|||
|
|||
public class AvaloniaRuntimeTypeSource : IRuntimeTypeSource |
|||
{ |
|||
private readonly RuntimeTypeSource inner; |
|||
|
|||
public AvaloniaRuntimeTypeSource(ITypeFactory typeFactory) |
|||
{ |
|||
var namespaceRegistry = new AvaloniaNamespaceRegistry(); |
|||
var featureProvider = new AvaloniaTypeFeatureProvider(); |
|||
var typeRepository = new AvaloniaTypeRepository(namespaceRegistry, typeFactory, featureProvider); |
|||
|
|||
inner = new RuntimeTypeSource(typeRepository, namespaceRegistry); |
|||
} |
|||
|
|||
public Namespace GetNamespace(string name) |
|||
{ |
|||
return inner.GetNamespace(name); |
|||
} |
|||
|
|||
public Namespace GetNamespaceByPrefix(string prefix) |
|||
{ |
|||
return inner.GetNamespaceByPrefix(prefix); |
|||
} |
|||
|
|||
public void RegisterPrefix(PrefixRegistration prefixRegistration) |
|||
{ |
|||
inner.RegisterPrefix(prefixRegistration); |
|||
} |
|||
|
|||
public void AddNamespace(XamlNamespace xamlNamespace) |
|||
{ |
|||
inner.AddNamespace(xamlNamespace); |
|||
} |
|||
|
|||
public IEnumerable<PrefixRegistration> RegisteredPrefixes => inner.RegisteredPrefixes; |
|||
|
|||
public XamlType GetByType(Type type) |
|||
{ |
|||
return inner.GetByType(type); |
|||
} |
|||
|
|||
public XamlType GetByQualifiedName(string qualifiedName) |
|||
{ |
|||
return inner.GetByQualifiedName(qualifiedName); |
|||
} |
|||
|
|||
public XamlType GetByPrefix(string prefix, string typeName) |
|||
{ |
|||
return inner.GetByPrefix(prefix, typeName); |
|||
} |
|||
|
|||
public XamlType GetByFullAddress(XamlTypeName xamlTypeName) |
|||
{ |
|||
return inner.GetByFullAddress(xamlTypeName); |
|||
} |
|||
|
|||
public Member GetMember(PropertyInfo propertyInfo) |
|||
{ |
|||
return inner.GetMember(propertyInfo); |
|||
} |
|||
|
|||
public AttachableMember GetAttachableMember(string name, MethodInfo getter, MethodInfo setter) |
|||
{ |
|||
return inner.GetAttachableMember(name, getter, setter); |
|||
} |
|||
} |
|||
} |
|||
@ -1,180 +0,0 @@ |
|||
// 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 System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Reflection; |
|||
using Avalonia.Collections; |
|||
using Avalonia.Controls; |
|||
using Avalonia.Controls.Templates; |
|||
using Avalonia.Input; |
|||
using Avalonia.Markup.Xaml.Converters; |
|||
using Avalonia.Media; |
|||
using Avalonia.Media.Imaging; |
|||
using Avalonia.Metadata; |
|||
using Avalonia.Styling; |
|||
using OmniXaml; |
|||
using OmniXaml.Builder; |
|||
using OmniXaml.TypeConversion; |
|||
using OmniXaml.TypeConversion.BuiltInConverters; |
|||
using OmniXaml.Typing; |
|||
using OmniMetadata = OmniXaml.Typing.Metadata; |
|||
|
|||
namespace Avalonia.Markup.Xaml.Context |
|||
{ |
|||
public class AvaloniaTypeFeatureProvider : ITypeFeatureProvider |
|||
{ |
|||
private Dictionary<Type, OmniMetadata> _metadata = |
|||
new Dictionary<Type, OmniMetadata>(); |
|||
|
|||
private Dictionary<Type, TypeConverterRegistration> _typeConverters = |
|||
new Dictionary<Type, TypeConverterRegistration>(); |
|||
|
|||
public IEnumerable<TypeConverterRegistration> TypeConverters => _typeConverters.Values; |
|||
|
|||
public AvaloniaTypeFeatureProvider() |
|||
{ |
|||
RegisterTypeConverters(); |
|||
} |
|||
|
|||
public string GetContentPropertyName(Type type) |
|||
{ |
|||
return GetMetadata(type)?.ContentProperty; |
|||
} |
|||
|
|||
public OmniMetadata GetMetadata(Type type) |
|||
{ |
|||
OmniMetadata result; |
|||
|
|||
if (!_metadata.TryGetValue(type, out result)) |
|||
{ |
|||
result = LoadMetadata(type); |
|||
_metadata.Add(type, result); |
|||
} |
|||
|
|||
return result; |
|||
} |
|||
|
|||
public ITypeConverter GetTypeConverter(Type type) |
|||
{ |
|||
TypeConverterRegistration result; |
|||
_typeConverters.TryGetValue(type, out result); |
|||
return result?.TypeConverter; |
|||
} |
|||
|
|||
public void RegisterMetadata(Type type, OmniMetadata metadata) |
|||
{ |
|||
_metadata.Add(type, metadata); |
|||
} |
|||
|
|||
public void RegisterTypeConverter(Type type, ITypeConverter converter) |
|||
{ |
|||
_typeConverters.Add(type, new TypeConverterRegistration(type, converter)); |
|||
} |
|||
|
|||
private static OmniMetadata LoadMetadata(Type type) |
|||
{ |
|||
return new OmniMetadata |
|||
{ |
|||
ContentProperty = GetContentProperty(type), |
|||
PropertyDependencies = GetPropertyDependencies(type), |
|||
RuntimePropertyName = type.GetRuntimeProperty("Name")?.Name, |
|||
}; |
|||
} |
|||
|
|||
private static string GetContentProperty(Type type) |
|||
{ |
|||
while (type != null) |
|||
{ |
|||
var properties = type.GetTypeInfo().DeclaredProperties |
|||
.Where(x => x.GetCustomAttribute<ContentAttribute>() != null); |
|||
string result = null; |
|||
|
|||
foreach (var property in properties) |
|||
{ |
|||
if (result != null) |
|||
{ |
|||
throw new Exception($"Content property defined more than once on {type}."); |
|||
} |
|||
|
|||
result = property.Name; |
|||
} |
|||
|
|||
if (result != null) |
|||
{ |
|||
return result; |
|||
} |
|||
|
|||
type = type.GetTypeInfo().BaseType; |
|||
} |
|||
|
|||
return null; |
|||
} |
|||
|
|||
private static DependencyRegistrations GetPropertyDependencies(Type type) |
|||
{ |
|||
var result = new List<DependencyRegistration>(); |
|||
|
|||
while (type != null) |
|||
{ |
|||
var registrations = type.GetTypeInfo().DeclaredProperties |
|||
.Select(x => new |
|||
{ |
|||
Property = x.Name, |
|||
Attributes = x.GetCustomAttributes<DependsOnAttribute>(), |
|||
}) |
|||
.Where(x => x.Attributes.Any()) |
|||
.SelectMany(x => x.Attributes.Select(y => new DependencyRegistration(x.Property, y.Name))); |
|||
|
|||
result.AddRange(registrations); |
|||
type = type.GetTypeInfo().BaseType; |
|||
} |
|||
|
|||
return result.Count > 0 ? new DependencyRegistrations(result) : null; |
|||
} |
|||
|
|||
private void RegisterTypeConverters() |
|||
{ |
|||
// HACK: For now these are hard-coded. Hopefully when the .NET Standard Platform
|
|||
// is available we can use the System.ComponentModel.TypeConverters so don't want to
|
|||
// spend time for now inventing a mechanism to register type converters if it's all
|
|||
// going to change.
|
|||
RegisterTypeConverter(typeof(string), new StringTypeConverter()); |
|||
RegisterTypeConverter(typeof(int), new IntTypeConverter()); |
|||
RegisterTypeConverter(typeof(long), new IntTypeConverter()); |
|||
RegisterTypeConverter(typeof(short), new IntTypeConverter()); |
|||
RegisterTypeConverter(typeof(double), new DoubleTypeConverter()); |
|||
RegisterTypeConverter(typeof(float), new IntTypeConverter()); |
|||
RegisterTypeConverter(typeof(bool), new BooleanConverter()); |
|||
RegisterTypeConverter(typeof(Type), new TypeTypeConverter()); |
|||
|
|||
RegisterTypeConverter(typeof(IBitmap), new BitmapTypeConverter()); |
|||
RegisterTypeConverter(typeof(IBrush), new BrushTypeConverter()); |
|||
RegisterTypeConverter(typeof(Color), new ColorTypeConverter()); |
|||
RegisterTypeConverter(typeof(Classes), new ClassesTypeConverter()); |
|||
RegisterTypeConverter(typeof(ColumnDefinitions), new ColumnDefinitionsTypeConverter()); |
|||
RegisterTypeConverter(typeof(DateTime), new DateTimeTypeConverter()); |
|||
RegisterTypeConverter(typeof(Geometry), new GeometryTypeConverter()); |
|||
RegisterTypeConverter(typeof(GridLength), new GridLengthTypeConverter()); |
|||
RegisterTypeConverter(typeof(KeyGesture), new KeyGestureConverter()); |
|||
RegisterTypeConverter(typeof(AvaloniaList<double>), new AvaloniaListTypeConverter<double>()); |
|||
RegisterTypeConverter(typeof(IMemberSelector), new MemberSelectorTypeConverter()); |
|||
RegisterTypeConverter(typeof(Point), new PointTypeConverter()); |
|||
RegisterTypeConverter(typeof(IList<Point>), new PointsListTypeConverter()); |
|||
RegisterTypeConverter(typeof(AvaloniaProperty), new AvaloniaPropertyTypeConverter()); |
|||
RegisterTypeConverter(typeof(RelativePoint), new RelativePointTypeConverter()); |
|||
RegisterTypeConverter(typeof(RelativeRect), new RelativeRectTypeConverter()); |
|||
RegisterTypeConverter(typeof(RowDefinitions), new RowDefinitionsTypeConverter()); |
|||
RegisterTypeConverter(typeof(Size), new SizeTypeConverter()); |
|||
RegisterTypeConverter(typeof(Selector), new SelectorTypeConverter()); |
|||
RegisterTypeConverter(typeof(SolidColorBrush), new BrushTypeConverter()); |
|||
RegisterTypeConverter(typeof(Thickness), new ThicknessTypeConverter()); |
|||
RegisterTypeConverter(typeof(TimeSpan), new TimeSpanTypeConverter()); |
|||
RegisterTypeConverter(typeof(Uri), new UriTypeConverter()); |
|||
RegisterTypeConverter(typeof(Cursor), new CursorTypeConverter()); |
|||
RegisterTypeConverter(typeof(WindowIcon), new IconTypeConverter()); |
|||
RegisterTypeConverter(typeof(FontWeight), new FontWeightConverter()); |
|||
} |
|||
} |
|||
} |
|||
@ -1,28 +0,0 @@ |
|||
// 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 OmniXaml; |
|||
using OmniXaml.Typing; |
|||
using Glass.Core; |
|||
|
|||
namespace Avalonia.Markup.Xaml.Context |
|||
{ |
|||
public class AvaloniaTypeRepository : TypeRepository |
|||
{ |
|||
private readonly ITypeFactory _typeFactory; |
|||
|
|||
public AvaloniaTypeRepository(INamespaceRegistry xamlNamespaceRegistry, |
|||
ITypeFactory typeFactory, |
|||
ITypeFeatureProvider featureProvider) : base(xamlNamespaceRegistry, typeFactory, featureProvider) |
|||
{ |
|||
_typeFactory = typeFactory; |
|||
} |
|||
|
|||
public override XamlType GetByType(Type type) |
|||
{ |
|||
Guard.ThrowIfNull(type, nameof(type)); |
|||
return new AvaloniaXamlType(type, this, _typeFactory, FeatureProvider); |
|||
} |
|||
} |
|||
} |
|||
@ -1,126 +0,0 @@ |
|||
// 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 System.Linq; |
|||
using System.Reflection; |
|||
using Glass; |
|||
using OmniXaml; |
|||
using OmniXaml.Builder; |
|||
using OmniXaml.TypeConversion; |
|||
using OmniXaml.Typing; |
|||
using Avalonia.Collections; |
|||
using Avalonia.Controls; |
|||
using Avalonia.Controls.Primitives; |
|||
using Avalonia.Controls.Templates; |
|||
using Avalonia.Input; |
|||
using Avalonia.Markup.Xaml.Converters; |
|||
using Avalonia.Markup.Xaml.Data; |
|||
using Avalonia.Media; |
|||
using Avalonia.Media.Imaging; |
|||
using Avalonia.Metadata; |
|||
using Avalonia.Platform; |
|||
using Avalonia.Styling; |
|||
using System.Collections.Generic; |
|||
|
|||
namespace Avalonia.Markup.Xaml.Context |
|||
{ |
|||
public class AvaloniaWiringContext : WiringContext |
|||
{ |
|||
private const string AvaloniaNs = "https://github.com/avaloniaui"; |
|||
|
|||
public AvaloniaWiringContext(ITypeFactory typeFactory) |
|||
: this(typeFactory, new TypeFeatureProvider(GetContentPropertyProvider(), GetConverterProvider())) |
|||
{ |
|||
} |
|||
|
|||
public AvaloniaWiringContext(ITypeFactory typeFactory, TypeFeatureProvider featureProvider) |
|||
: base(CreateTypeContext(typeFactory, featureProvider), featureProvider) |
|||
{ |
|||
} |
|||
|
|||
private static ITypeContext CreateTypeContext(ITypeFactory typeFactory, TypeFeatureProvider featureProvider) |
|||
{ |
|||
var xamlNamespaceRegistry = CreateXamlNamespaceRegistry(); |
|||
var typeRepository = new AvaloniaTypeRepository(xamlNamespaceRegistry, typeFactory, featureProvider); |
|||
|
|||
typeRepository.RegisterMetadata(new GenericMetadata<Visual>().WithRuntimeNameProperty(d => d.Name)); |
|||
typeRepository.RegisterMetadata(new GenericMetadata<Setter>().WithMemberDependency(x => x.Value, x => x.Property)); |
|||
typeRepository.RegisterMetadata( |
|||
new GenericMetadata<SelectingItemsControl>() |
|||
.WithMemberDependency(x => x.SelectedIndex, x => x.Items) |
|||
.WithMemberDependency(x => x.SelectedItem, x => x.Items)); |
|||
|
|||
return new TypeContext(typeRepository, xamlNamespaceRegistry, typeFactory); |
|||
} |
|||
|
|||
private static XamlNamespaceRegistry CreateXamlNamespaceRegistry() |
|||
{ |
|||
var xamlNamespaceRegistry = new XamlNamespaceRegistry(); |
|||
|
|||
var forcedAssemblies = new[] |
|||
{ |
|||
typeof(Binding), |
|||
typeof(Control), |
|||
typeof(IValueConverter), |
|||
typeof(Style), |
|||
}.Select(t => t.GetTypeInfo().Assembly); |
|||
|
|||
foreach (var nsa in |
|||
forcedAssemblies |
|||
.Concat(AvaloniaLocator.Current.GetService<IPclPlatformWrapper>().GetLoadedAssemblies()) |
|||
.Distinct() |
|||
.SelectMany(asm |
|||
=> asm.GetCustomAttributes<XmlnsDefinitionAttribute>().Select(attr => new {asm, attr})) |
|||
.GroupBy(entry => entry.attr.XmlNamespace)) |
|||
{ |
|||
var def = XamlNamespace.Map(nsa.Key) |
|||
.With(nsa.GroupBy(x => x.asm).Select( |
|||
a => Route.Assembly(a.Key) |
|||
.WithNamespaces(a.Select(entry => entry.attr.ClrNamespace).ToList()) |
|||
)); |
|||
xamlNamespaceRegistry.AddNamespace(def); |
|||
} |
|||
xamlNamespaceRegistry.RegisterPrefix(new PrefixRegistration(string.Empty, AvaloniaNs)); |
|||
|
|||
return xamlNamespaceRegistry; |
|||
} |
|||
|
|||
private static ITypeConverterProvider GetConverterProvider() |
|||
{ |
|||
var typeConverterProvider = new TypeConverterProvider(); |
|||
var converters = new[] |
|||
{ |
|||
new TypeConverterRegistration(typeof(IBitmap), new BitmapTypeConverter()), |
|||
new TypeConverterRegistration(typeof(Brush), new BrushTypeConverter()), |
|||
new TypeConverterRegistration(typeof(Color), new ColorTypeConverter()), |
|||
new TypeConverterRegistration(typeof(Classes), new ClassesTypeConverter()), |
|||
new TypeConverterRegistration(typeof(ColumnDefinitions), new ColumnDefinitionsTypeConverter()), |
|||
new TypeConverterRegistration(typeof(Geometry), new GeometryTypeConverter()), |
|||
new TypeConverterRegistration(typeof(GridLength), new GridLengthTypeConverter()), |
|||
new TypeConverterRegistration(typeof(KeyGesture), new KeyGestureConverter()), |
|||
new TypeConverterRegistration(typeof(AvaloniaList<double>), new AvaloniaListTypeConverter<double>()), |
|||
new TypeConverterRegistration(typeof(IMemberSelector), new MemberSelectorTypeConverter()), |
|||
new TypeConverterRegistration(typeof(Point), new PointTypeConverter()), |
|||
new TypeConverterRegistration(typeof(IList<Point>), new PointsListTypeConverter()), |
|||
new TypeConverterRegistration(typeof(AvaloniaProperty), new AvaloniaPropertyTypeConverter()), |
|||
new TypeConverterRegistration(typeof(RelativePoint), new RelativePointTypeConverter()), |
|||
new TypeConverterRegistration(typeof(RelativeRect), new RelativeRectTypeConverter()), |
|||
new TypeConverterRegistration(typeof(RowDefinitions), new RowDefinitionsTypeConverter()), |
|||
new TypeConverterRegistration(typeof(Selector), new SelectorTypeConverter()), |
|||
new TypeConverterRegistration(typeof(Thickness), new ThicknessTypeConverter()), |
|||
new TypeConverterRegistration(typeof(TimeSpan), new TimeSpanTypeConverter()), |
|||
new TypeConverterRegistration(typeof(Uri), new UriTypeConverter()), |
|||
new TypeConverterRegistration(typeof(Cursor), new CursorTypeConverter()) |
|||
}; |
|||
|
|||
typeConverterProvider.AddAll(converters); |
|||
return typeConverterProvider; |
|||
} |
|||
|
|||
private static IContentPropertyProvider GetContentPropertyProvider() |
|||
{ |
|||
return new AvaloniaContentPropertyProvider(); |
|||
} |
|||
} |
|||
} |
|||
@ -1,31 +0,0 @@ |
|||
// 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.Data; |
|||
using OmniXaml; |
|||
using OmniXaml.Typing; |
|||
using System; |
|||
|
|||
namespace Avalonia.Markup.Xaml.Context |
|||
{ |
|||
public class AvaloniaXamlMember : Member |
|||
{ |
|||
public AvaloniaXamlMember(string name, |
|||
XamlType owner, |
|||
ITypeRepository xamlTypeRepository, |
|||
ITypeFeatureProvider featureProvider) |
|||
: base(name, owner, xamlTypeRepository, featureProvider) |
|||
{ |
|||
} |
|||
|
|||
protected override IMemberValuePlugin LookupXamlMemberValueConnector() |
|||
{ |
|||
return new AvaloniaMemberValuePlugin(this); |
|||
} |
|||
|
|||
public override string ToString() |
|||
{ |
|||
return "Avalonia XAML Member " + base.ToString(); |
|||
} |
|||
} |
|||
} |
|||
@ -1,61 +0,0 @@ |
|||
// 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 System.Reflection; |
|||
using OmniXaml; |
|||
using OmniXaml.Typing; |
|||
using Avalonia.Controls; |
|||
|
|||
namespace Avalonia.Markup.Xaml.Context |
|||
{ |
|||
public class AvaloniaXamlType : XamlType |
|||
{ |
|||
public AvaloniaXamlType(Type type, |
|||
ITypeRepository typeRepository, |
|||
ITypeFactory typeFactory, |
|||
ITypeFeatureProvider featureProvider) : base(type, typeRepository, typeFactory, featureProvider) |
|||
{ |
|||
} |
|||
|
|||
public override OmniXaml.INameScope GetNamescope(object instance) |
|||
{ |
|||
var result = instance as OmniXaml.INameScope; |
|||
|
|||
if (result == null) |
|||
{ |
|||
var control = instance as Control; |
|||
|
|||
if (control != null) |
|||
{ |
|||
var avaloniaNs = (instance as Avalonia.Controls.INameScope) ?? NameScope.GetNameScope(control); |
|||
|
|||
if (avaloniaNs != null) |
|||
{ |
|||
result = new NameScopeWrapper(avaloniaNs); |
|||
} |
|||
} |
|||
} |
|||
|
|||
return result; |
|||
} |
|||
|
|||
protected override Member LookupMember(string name) |
|||
{ |
|||
return new AvaloniaXamlMember(name, this, TypeRepository, FeatureProvider); |
|||
} |
|||
|
|||
protected override AttachableMember LookupAttachableMember(string name) |
|||
{ |
|||
// OmniXAML seems to require a getter and setter even though we don't use them.
|
|||
var getter = UnderlyingType.GetTypeInfo().GetDeclaredMethod("Get" + name); |
|||
var setter = UnderlyingType.GetTypeInfo().GetDeclaredMethod("Set" + name); |
|||
return new AvaloniaAttachableXamlMember(name, this, getter, setter, TypeRepository, FeatureProvider); |
|||
} |
|||
|
|||
public override string ToString() |
|||
{ |
|||
return "Avalonia XAML Type " + base.ToString(); |
|||
} |
|||
} |
|||
} |
|||
@ -1,30 +0,0 @@ |
|||
// 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.
|
|||
|
|||
namespace Avalonia.Markup.Xaml.Context |
|||
{ |
|||
internal class NameScopeWrapper : OmniXaml.INameScope |
|||
{ |
|||
private readonly Avalonia.Controls.INameScope _inner; |
|||
|
|||
public NameScopeWrapper(Avalonia.Controls.INameScope inner) |
|||
{ |
|||
_inner = inner; |
|||
} |
|||
|
|||
public object Find(string name) |
|||
{ |
|||
return _inner.Find(name); |
|||
} |
|||
|
|||
public void Register(string name, object scopedElement) |
|||
{ |
|||
_inner.Register(name, scopedElement); |
|||
} |
|||
|
|||
public void Unregister(string name) |
|||
{ |
|||
_inner.Unregister(name); |
|||
} |
|||
} |
|||
} |
|||
@ -1,174 +0,0 @@ |
|||
// 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 System.Linq; |
|||
using System.Reflection; |
|||
using System.Runtime.CompilerServices; |
|||
using OmniXaml.ObjectAssembler; |
|||
using OmniXaml.TypeConversion; |
|||
using OmniXaml.Typing; |
|||
using Avalonia.Controls; |
|||
using Avalonia.Data; |
|||
using Avalonia.Markup.Xaml.Data; |
|||
using Avalonia.Styling; |
|||
|
|||
namespace Avalonia.Markup.Xaml.Context |
|||
{ |
|||
internal static class PropertyAccessor |
|||
{ |
|||
public static void SetValue( |
|||
object instance, |
|||
MutableMember member, |
|||
object value, |
|||
IValueContext context) |
|||
{ |
|||
var avaloniaProperty = FindAvaloniaProperty(instance, member); |
|||
|
|||
if (value is IBinding) |
|||
{ |
|||
SetBinding(instance, member, avaloniaProperty, context, (IBinding)value); |
|||
} |
|||
else if (avaloniaProperty != null) |
|||
{ |
|||
((AvaloniaObject)instance).SetValue(avaloniaProperty, value); |
|||
} |
|||
else if (instance is Setter && member.Name == "Value") |
|||
{ |
|||
// TODO: Make this more generic somehow.
|
|||
var setter = (Setter)instance; |
|||
var targetType = setter.Property.PropertyType; |
|||
var xamlType = member.TypeRepository.GetByType(targetType); |
|||
var convertedValue = default(object); |
|||
|
|||
if (CommonValueConversion.TryConvert(value, xamlType, context, out convertedValue)) |
|||
{ |
|||
SetClrProperty(instance, member, convertedValue); |
|||
} |
|||
} |
|||
else |
|||
{ |
|||
SetClrProperty(instance, member, value); |
|||
} |
|||
} |
|||
|
|||
private static AvaloniaProperty FindAvaloniaProperty(object instance, MutableMember member) |
|||
{ |
|||
var registry = AvaloniaPropertyRegistry.Instance; |
|||
var attached = member as AvaloniaAttachableXamlMember; |
|||
var target = instance as AvaloniaObject; |
|||
|
|||
if (target == null) |
|||
{ |
|||
return null; |
|||
} |
|||
|
|||
if (attached == null) |
|||
{ |
|||
return registry.FindRegistered(target, member.Name); |
|||
} |
|||
else |
|||
{ |
|||
var ownerType = attached.DeclaringType.UnderlyingType; |
|||
|
|||
RuntimeHelpers.RunClassConstructor(ownerType.TypeHandle); |
|||
|
|||
return registry.GetRegistered(target) |
|||
.Where(x => x.OwnerType == ownerType && x.Name == attached.Name) |
|||
.FirstOrDefault(); |
|||
} |
|||
} |
|||
|
|||
private static void SetBinding( |
|||
object instance, |
|||
MutableMember member, |
|||
AvaloniaProperty property, |
|||
IValueContext context, |
|||
IBinding binding) |
|||
{ |
|||
if (!(AssignBinding(instance, member, binding) || |
|||
ApplyBinding(instance, property, context, binding))) |
|||
{ |
|||
throw new InvalidOperationException( |
|||
$"Cannot assign to '{member.Name}' on '{instance.GetType()}"); |
|||
} |
|||
} |
|||
|
|||
private static void SetClrProperty(object instance, MutableMember member, object value) |
|||
{ |
|||
if (member.IsAttachable) |
|||
{ |
|||
member.Setter.Invoke(null, new[] { instance, value }); |
|||
} |
|||
else |
|||
{ |
|||
member.Setter.Invoke(instance, new[] { value }); |
|||
} |
|||
} |
|||
|
|||
private static bool AssignBinding(object instance, MutableMember member, IBinding binding) |
|||
{ |
|||
var property = instance.GetType() |
|||
.GetRuntimeProperties() |
|||
.FirstOrDefault(x => x.Name == member.Name); |
|||
|
|||
if (property?.GetCustomAttribute<AssignBindingAttribute>() != null) |
|||
{ |
|||
property.SetValue(instance, binding); |
|||
return true; |
|||
} |
|||
|
|||
return false; |
|||
} |
|||
|
|||
private static bool ApplyBinding( |
|||
object instance, |
|||
AvaloniaProperty property, |
|||
IValueContext context, |
|||
IBinding binding) |
|||
{ |
|||
if (property == null) |
|||
{ |
|||
return false; |
|||
} |
|||
|
|||
var control = instance as IControl; |
|||
|
|||
if (control != null) |
|||
{ |
|||
if (property != Control.DataContextProperty) |
|||
{ |
|||
DelayedBinding.Add(control, property, binding); |
|||
} |
|||
else |
|||
{ |
|||
control.Bind(property, binding); |
|||
} |
|||
} |
|||
else |
|||
{ |
|||
// The target is not a control, so we need to find an anchor that will let us look
|
|||
// up named controls and style resources. First look for the closest IControl in
|
|||
// the TopDownValueContext.
|
|||
object anchor = context.TopDownValueContext.StoredInstances |
|||
.Select(x => x.Instance) |
|||
.OfType<IControl>() |
|||
.LastOrDefault(); |
|||
|
|||
// If a control was not found, then try to find the highest-level style as the XAML
|
|||
// file could be a XAML file containing only styles.
|
|||
if (anchor == null) |
|||
{ |
|||
anchor = context.TopDownValueContext.StoredInstances |
|||
.Select(x => x.Instance) |
|||
.OfType<IStyle>() |
|||
.FirstOrDefault(); |
|||
} |
|||
|
|||
((IAvaloniaObject)instance).Bind(property, binding, anchor); |
|||
} |
|||
|
|||
return true; |
|||
} |
|||
} |
|||
} |
|||
@ -1,58 +0,0 @@ |
|||
using OmniXaml.TypeConversion; |
|||
using System; |
|||
using System.Globalization; |
|||
|
|||
namespace Avalonia.Markup.Xaml.Converters |
|||
{ |
|||
public class DateTimeTypeConverter : ITypeConverter |
|||
{ |
|||
public object ConvertFrom(IValueContext context, CultureInfo culture, object value) |
|||
{ |
|||
if (culture == null) |
|||
{ |
|||
throw new ArgumentNullException("culture"); |
|||
} |
|||
|
|||
if (value == null) |
|||
{ |
|||
throw new ArgumentNullException("value"); |
|||
} |
|||
|
|||
DateTimeFormatInfo dateTimeFormatInfo = (DateTimeFormatInfo)culture.GetFormat(typeof(DateTimeFormatInfo)); |
|||
DateTime d = DateTime.ParseExact(value.ToString(), dateTimeFormatInfo.ShortDatePattern, culture); |
|||
return d; |
|||
} |
|||
|
|||
public object ConvertTo(IValueContext context, CultureInfo culture, object value, Type destinationType) |
|||
{ |
|||
if (destinationType == null) |
|||
{ |
|||
throw new ArgumentNullException("destinationType"); |
|||
} |
|||
|
|||
if (culture == null) |
|||
{ |
|||
throw new ArgumentNullException("culture"); |
|||
} |
|||
|
|||
DateTime? d = value as DateTime?; |
|||
|
|||
if (!d.HasValue || destinationType != typeof(string)) |
|||
{ |
|||
throw new NotSupportedException(); |
|||
} |
|||
DateTimeFormatInfo dateTimeFormatInfo = (DateTimeFormatInfo)culture.GetFormat(typeof(DateTimeFormatInfo)); |
|||
return d.Value.ToString(dateTimeFormatInfo.ShortDatePattern, culture); |
|||
} |
|||
|
|||
public bool CanConvertTo(IValueContext context, Type destinationType) |
|||
{ |
|||
return destinationType == typeof(string); |
|||
} |
|||
|
|||
public bool CanConvertFrom(IValueContext context, Type sourceType) |
|||
{ |
|||
return sourceType == typeof(string); |
|||
} |
|||
} |
|||
} |
|||
@ -1,39 +0,0 @@ |
|||
namespace Avalonia.Markup.Xaml.Converters |
|||
{ |
|||
using Avalonia.Media; |
|||
using OmniXaml.TypeConversion; |
|||
using System; |
|||
using System.Globalization; |
|||
|
|||
public class FontWeightConverter : ITypeConverter |
|||
{ |
|||
public bool CanConvertFrom(IValueContext context, Type sourceType) |
|||
{ |
|||
return sourceType == typeof(string); |
|||
} |
|||
|
|||
public bool CanConvertTo(IValueContext context, Type destinationType) |
|||
{ |
|||
return false; |
|||
} |
|||
|
|||
public object ConvertFrom(IValueContext context, CultureInfo culture, object value) |
|||
{ |
|||
FontWeight result; |
|||
|
|||
if (Enum.TryParse(value as string, out result)) |
|||
{ |
|||
return result; |
|||
} |
|||
else |
|||
{ |
|||
throw new ArgumentException("unable to convert parameter to FontWeight"); |
|||
} |
|||
} |
|||
|
|||
public object ConvertTo(IValueContext context, CultureInfo culture, object value, Type destinationType) |
|||
{ |
|||
throw new NotImplementedException(); |
|||
} |
|||
} |
|||
} |
|||
@ -1,30 +1,24 @@ |
|||
// 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 System.Globalization; |
|||
using Avalonia.Media; |
|||
|
|||
namespace Avalonia.Markup.Xaml.Converters |
|||
{ |
|||
using System; |
|||
using System.Globalization; |
|||
using Media; |
|||
using OmniXaml.TypeConversion; |
|||
using System.ComponentModel; |
|||
|
|||
public class GeometryTypeConverter : ITypeConverter |
|||
public class GeometryTypeConverter : TypeConverter |
|||
{ |
|||
public bool CanConvertFrom(IValueContext context, Type sourceType) |
|||
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) |
|||
{ |
|||
return sourceType == typeof(string); |
|||
} |
|||
|
|||
public bool CanConvertTo(IValueContext context, Type destinationType) |
|||
{ |
|||
return false; |
|||
} |
|||
|
|||
public object ConvertFrom(IValueContext context, CultureInfo culture, object value) |
|||
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) |
|||
{ |
|||
return StreamGeometry.Parse((string)value); |
|||
} |
|||
|
|||
public object ConvertTo(IValueContext context, CultureInfo culture, object value, Type destinationType) |
|||
{ |
|||
throw new NotImplementedException(); |
|||
} |
|||
} |
|||
} |
|||
@ -1,70 +1,55 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Globalization; |
|||
using System.Linq; |
|||
using System.Reflection; |
|||
using System.Text; |
|||
using System.Threading.Tasks; |
|||
// 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.Controls; |
|||
using Avalonia.Media.Imaging; |
|||
using Avalonia.Platform; |
|||
using OmniXaml.TypeConversion; |
|||
using System; |
|||
using System.Globalization; |
|||
|
|||
namespace Avalonia.Markup.Xaml.Converters |
|||
{ |
|||
class IconTypeConverter : ITypeConverter |
|||
{ |
|||
public bool CanConvertFrom(IValueContext context, Type sourceType) |
|||
{ |
|||
return sourceType == typeof(string) || typeof(IBitmap).GetTypeInfo().IsAssignableFrom(sourceType.GetTypeInfo()); |
|||
} |
|||
using Portable.Xaml.ComponentModel; |
|||
using System.ComponentModel; |
|||
|
|||
public bool CanConvertTo(IValueContext context, Type destinationType) |
|||
public class IconTypeConverter : TypeConverter |
|||
{ |
|||
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) |
|||
{ |
|||
return false; |
|||
return sourceType == typeof(string); |
|||
} |
|||
|
|||
public object ConvertFrom(IValueContext context, CultureInfo culture, object value) |
|||
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) |
|||
{ |
|||
var path = value as string; |
|||
if (path != null) |
|||
{ |
|||
return CreateIconFromPath(context, path); |
|||
return CreateIconFromPath(context, path); |
|||
} |
|||
|
|||
var bitmap = value as IBitmap; |
|||
if (bitmap != null) |
|||
{ |
|||
return new WindowIcon(bitmap); |
|||
} |
|||
|
|||
throw new NotSupportedException(); |
|||
} |
|||
|
|||
private WindowIcon CreateIconFromPath(IValueContext context, string path) |
|||
private WindowIcon CreateIconFromPath(ITypeDescriptorContext context, string path) |
|||
{ |
|||
var uri = new Uri(path, UriKind.RelativeOrAbsolute); |
|||
var baseUri = GetBaseUri(context); |
|||
var scheme = uri.IsAbsoluteUri ? uri.Scheme : "file"; |
|||
|
|||
switch (scheme) |
|||
{ |
|||
case "file": |
|||
return new WindowIcon(path); |
|||
|
|||
default: |
|||
var assets = AvaloniaLocator.Current.GetService<IAssetLoader>(); |
|||
return new WindowIcon(assets.Open(uri, baseUri)); |
|||
return new WindowIcon(assets.Open(uri, context.GetBaseUri())); |
|||
} |
|||
} |
|||
|
|||
public object ConvertTo(IValueContext context, CultureInfo culture, object value, Type destinationType) |
|||
{ |
|||
throw new NotImplementedException(); |
|||
} |
|||
|
|||
private Uri GetBaseUri(IValueContext context) |
|||
{ |
|||
object result; |
|||
context.ParsingDictionary.TryGetValue("Uri", out result); |
|||
return result as Uri; |
|||
} |
|||
} |
|||
} |
|||
|
|||
@ -1,30 +1,24 @@ |
|||
// 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 System.Globalization; |
|||
using OmniXaml.TypeConversion; |
|||
using Avalonia.Input; |
|||
|
|||
namespace Avalonia.Markup.Xaml.Converters |
|||
{ |
|||
class KeyGestureConverter : ITypeConverter |
|||
using System.ComponentModel; |
|||
|
|||
public class KeyGestureConverter : TypeConverter |
|||
{ |
|||
public bool CanConvertFrom(IValueContext context, Type sourceType) |
|||
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) |
|||
{ |
|||
return sourceType == typeof(string); |
|||
} |
|||
|
|||
public bool CanConvertTo(IValueContext context, Type destinationType) |
|||
{ |
|||
return false; |
|||
} |
|||
|
|||
public object ConvertFrom(IValueContext context, CultureInfo culture, object value) |
|||
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) |
|||
{ |
|||
return KeyGesture.Parse((string)value); |
|||
} |
|||
|
|||
public object ConvertTo(IValueContext context, CultureInfo culture, object value, Type destinationType) |
|||
{ |
|||
throw new NotImplementedException(); |
|||
} |
|||
} |
|||
} |
|||
|
|||
@ -0,0 +1,49 @@ |
|||
// 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.Styling; |
|||
using Portable.Xaml; |
|||
using Portable.Xaml.ComponentModel; |
|||
using System.ComponentModel; |
|||
using Portable.Xaml.Markup; |
|||
using System; |
|||
using System.Globalization; |
|||
|
|||
namespace Avalonia.Markup.Xaml.Converters |
|||
{ |
|||
public class SetterValueTypeConverter : TypeConverter |
|||
{ |
|||
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) |
|||
{ |
|||
return sourceType == typeof(string); |
|||
} |
|||
|
|||
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) |
|||
{ |
|||
object setter = context.GetService<IProvideValueTarget>().TargetObject; |
|||
var schemaContext = context.GetService<IXamlSchemaContextProvider>().SchemaContext; |
|||
|
|||
return ConvertSetterValue(schemaContext, (setter as Setter), value); |
|||
} |
|||
|
|||
[Obsolete("TODO: try assosiate Setter.Value property with SetterValueTypeConverter, so far coouldn't make it :(")] |
|||
internal static object ConvertSetterValue(XamlSchemaContext context, Setter setter, object value) |
|||
{ |
|||
Type targetType = setter?.Property?.PropertyType; |
|||
|
|||
if (targetType == null) |
|||
{ |
|||
return value; |
|||
} |
|||
|
|||
var ttConv = context.GetXamlType(targetType)?.TypeConverter?.ConverterInstance; |
|||
|
|||
if (ttConv != null) |
|||
{ |
|||
value = ttConv.ConvertFromString(value as string); |
|||
} |
|||
|
|||
return value; |
|||
} |
|||
} |
|||
} |
|||
@ -1,32 +0,0 @@ |
|||
// 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 System.Globalization; |
|||
using OmniXaml.TypeConversion; |
|||
|
|||
namespace Avalonia.Markup.Xaml.Converters |
|||
{ |
|||
public class UriTypeConverter : ITypeConverter |
|||
{ |
|||
public bool CanConvertFrom(IValueContext context, Type sourceType) |
|||
{ |
|||
return sourceType == typeof(string); |
|||
} |
|||
|
|||
public bool CanConvertTo(IValueContext context, Type destinationType) |
|||
{ |
|||
return false; |
|||
} |
|||
|
|||
public object ConvertFrom(IValueContext context, CultureInfo culture, object value) |
|||
{ |
|||
return new Uri((string)value); |
|||
} |
|||
|
|||
public object ConvertTo(IValueContext context, CultureInfo culture, object value, Type destinationType) |
|||
{ |
|||
throw new NotImplementedException(); |
|||
} |
|||
} |
|||
} |
|||
@ -1,27 +0,0 @@ |
|||
// 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 System.ComponentModel; |
|||
|
|||
namespace Avalonia.Markup.Xaml.Data |
|||
{ |
|||
public class SourceBindingEndpoint |
|||
{ |
|||
public Type PropertyType { get; } |
|||
|
|||
public INotifyPropertyChanged Source { get; } |
|||
|
|||
public dynamic PropertyGetter { get; } |
|||
|
|||
public Delegate PropertySetter { get; } |
|||
|
|||
public SourceBindingEndpoint(INotifyPropertyChanged source, Type propertyType, dynamic propertyGetter, Delegate propertySetter) |
|||
{ |
|||
Source = source; |
|||
PropertyType = propertyType; |
|||
PropertyGetter = propertyGetter; |
|||
PropertySetter = propertySetter; |
|||
} |
|||
} |
|||
} |
|||
@ -1,18 +0,0 @@ |
|||
// 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.
|
|||
|
|||
namespace Avalonia.Markup.Xaml.Data |
|||
{ |
|||
public class TargetBindingEndpoint |
|||
{ |
|||
public AvaloniaObject Object { get; } |
|||
|
|||
public AvaloniaProperty Property { get; } |
|||
|
|||
public TargetBindingEndpoint(AvaloniaObject obj, AvaloniaProperty property) |
|||
{ |
|||
Object = obj; |
|||
Property = property; |
|||
} |
|||
} |
|||
} |
|||
@ -1,86 +0,0 @@ |
|||
// 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 System.Linq; |
|||
using System.Reflection; |
|||
using OmniXaml; |
|||
using Glass.Core; |
|||
|
|||
namespace Avalonia.Markup.Xaml.MarkupExtensions.Standard |
|||
{ |
|||
public class StaticExtension : MarkupExtension |
|||
{ |
|||
public StaticExtension() |
|||
{ |
|||
} |
|||
|
|||
public StaticExtension(string identifier) |
|||
{ |
|||
Identifier = identifier; |
|||
} |
|||
|
|||
public string Identifier { get; set; } |
|||
|
|||
public override object ProvideValue(MarkupExtensionContext markupExtensionContext) |
|||
{ |
|||
var typeRepository = markupExtensionContext.ValueContext.TypeRepository; |
|||
var typeAndMember = GetTypeAndMember(Identifier); |
|||
var prefixAndType = GetPrefixAndType(typeAndMember.Item1); |
|||
var xamlType = typeRepository.GetByPrefix(prefixAndType.Item1, prefixAndType.Item2); |
|||
return GetValue(xamlType.UnderlyingType, typeAndMember.Item2); |
|||
} |
|||
|
|||
private static Tuple<string, string> GetTypeAndMember(string s) |
|||
{ |
|||
var parts = s.Split('.'); |
|||
|
|||
if (parts.Length != 2) |
|||
{ |
|||
throw new ArgumentException("Static member must be in the form Type.Member."); |
|||
} |
|||
|
|||
return Tuple.Create(parts[0], parts[1]); |
|||
} |
|||
|
|||
private static Tuple<string, string> GetPrefixAndType(string s) |
|||
{ |
|||
if (s.Contains(":")) |
|||
{ |
|||
return s.Dicotomize(':'); |
|||
} |
|||
else |
|||
{ |
|||
return new Tuple<string, string>(string.Empty, s); |
|||
} |
|||
} |
|||
|
|||
private object GetValue(Type type, string name) |
|||
{ |
|||
var t = type; |
|||
|
|||
while (t != null) |
|||
{ |
|||
var result = t.GetTypeInfo().DeclaredMembers.FirstOrDefault(x => x.Name == name); |
|||
|
|||
if (result is PropertyInfo) |
|||
{ |
|||
var property = ((PropertyInfo)result); |
|||
|
|||
if (property.GetMethod.IsStatic) |
|||
{ |
|||
return ((PropertyInfo)result).GetValue(null); |
|||
} |
|||
} |
|||
else if (result is FieldInfo) |
|||
{ |
|||
return ((FieldInfo)result).GetValue(null); |
|||
} |
|||
|
|||
t = t.GetTypeInfo().BaseType; |
|||
} |
|||
|
|||
throw new ArgumentException($"Static member '{type}.{name}' not found."); |
|||
} |
|||
} |
|||
} |
|||
@ -1,49 +0,0 @@ |
|||
// 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 OmniXaml; |
|||
using OmniXaml.Attributes; |
|||
using OmniXaml.Typing; |
|||
using Glass.Core; |
|||
|
|||
namespace Avalonia.Markup.Xaml.MarkupExtensions.Standard |
|||
{ |
|||
[ContentProperty("TargetType")] |
|||
public class TypeExtension : MarkupExtension |
|||
{ |
|||
public Type Type { get; set; } |
|||
|
|||
public TypeExtension() |
|||
{ |
|||
} |
|||
|
|||
public TypeExtension(Type type) |
|||
{ |
|||
Type = type; |
|||
} |
|||
|
|||
public string TypeName { get; set; } |
|||
|
|||
private Type ResolveFromString(string type, ITypeRepository typeRepository) |
|||
{ |
|||
Guard.ThrowIfNull(type, nameof(type)); |
|||
|
|||
var split = type.Split(':'); |
|||
var prefix = split.Length == 1 ? split[0] : null; |
|||
var typeName = split.Length == 1 ? split[1] : split[0]; |
|||
var xamlType = typeRepository.GetByPrefix(prefix, typeName); |
|||
return xamlType.UnderlyingType; |
|||
} |
|||
|
|||
public override object ProvideValue(MarkupExtensionContext markupExtensionContext) |
|||
{ |
|||
if (Type != null) |
|||
{ |
|||
return Type; |
|||
} |
|||
|
|||
return ResolveFromString(TypeName, markupExtensionContext.ValueContext.TypeRepository); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,30 @@ |
|||
// 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 System.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; } |
|||
|
|||
} |
|||
} |
|||
@ -1 +0,0 @@ |
|||
Subproject commit 544af79d218127b4174da4be19896c5ca78eaa5d |
|||
@ -0,0 +1,39 @@ |
|||
using Avalonia.Markup.Xaml.Templates; |
|||
using avm = Avalonia.Metadata; |
|||
using pm = Portable.Xaml.Markup; |
|||
|
|||
namespace Avalonia.Markup.Xaml.PortableXaml |
|||
{ |
|||
internal static class AttributeExtensions |
|||
{ |
|||
public static pm.XamlDeferLoadAttribute ToPortableXaml(this avm.TemplateContentAttribute attrib) |
|||
{ |
|||
if (attrib == null) |
|||
{ |
|||
return null; |
|||
} |
|||
|
|||
return new pm.XamlDeferLoadAttribute(typeof(TemplateLoader), typeof(TemplateContent)); |
|||
} |
|||
|
|||
public static pm.AmbientAttribute ToPortableXaml(this avm.AmbientAttribute attrib) |
|||
{ |
|||
if (attrib == null) |
|||
{ |
|||
return null; |
|||
} |
|||
|
|||
return new pm.AmbientAttribute(); |
|||
} |
|||
|
|||
public static pm.DependsOnAttribute ToPortableXaml(this avm.DependsOnAttribute attrib) |
|||
{ |
|||
if (attrib == null) |
|||
{ |
|||
return null; |
|||
} |
|||
|
|||
return new pm.DependsOnAttribute(attrib.Name); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,86 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Globalization; |
|||
using System.Reflection; |
|||
using Avalonia.Markup.Xaml.Converters; |
|||
using Avalonia.Media; |
|||
using Avalonia.Media.Imaging; |
|||
using Avalonia.Styling; |
|||
using Portable.Xaml.ComponentModel; |
|||
using System.ComponentModel; |
|||
using Avalonia.Controls; |
|||
using Avalonia.Input; |
|||
using Avalonia.Collections; |
|||
using Avalonia.Controls.Templates; |
|||
|
|||
namespace Avalonia.Markup.Xaml.PortableXaml |
|||
{ |
|||
public class AvaloniaDefaultTypeConverters |
|||
{ |
|||
private static Dictionary<Type, Type> _defaultConverters = new Dictionary<Type, Type>() |
|||
{ |
|||
//avalonia default converters
|
|||
{ typeof(IBitmap), typeof(BitmapTypeConverter)}, |
|||
{ typeof(IBrush), typeof(BrushTypeConverter) }, |
|||
{ typeof(Color), typeof(ColorTypeConverter) }, |
|||
{ typeof(Classes), typeof(ClassesTypeConverter) }, |
|||
{ typeof(ColumnDefinitions), typeof(ColumnDefinitionsTypeConverter) }, |
|||
//{ typeof(DateTime), typeof(DateTimeTypeConverter) },
|
|||
{ typeof(Geometry), typeof(GeometryTypeConverter) }, |
|||
{ typeof(GridLength), typeof(GridLengthTypeConverter) }, |
|||
{ typeof(KeyGesture), typeof(KeyGestureConverter) }, |
|||
{ typeof(AvaloniaList<double>), typeof(AvaloniaListTypeConverter<double>) }, |
|||
{ typeof(IMemberSelector), typeof(MemberSelectorTypeConverter) }, |
|||
{ typeof(Point), typeof(PointTypeConverter) }, |
|||
{ typeof(IList<Point>), typeof(PointsListTypeConverter) }, |
|||
{ typeof(AvaloniaProperty), typeof(AvaloniaPropertyTypeConverter) }, |
|||
{ typeof(RelativePoint), typeof(RelativePointTypeConverter) }, |
|||
{ typeof(RelativeRect), typeof(RelativeRectTypeConverter) }, |
|||
{ typeof(RowDefinitions), typeof(RowDefinitionsTypeConverter) }, |
|||
{ typeof(Size), typeof(SizeTypeConverter) }, |
|||
{ typeof(Selector), typeof(SelectorTypeConverter)}, |
|||
{ typeof(SolidColorBrush), typeof(BrushTypeConverter) }, |
|||
{ typeof(Thickness), typeof(ThicknessTypeConverter) }, |
|||
{ typeof(TimeSpan), typeof(TimeSpanTypeConverter) }, |
|||
//{ typeof(Uri), typeof(Converters.UriTypeConverter) },
|
|||
{ typeof(Cursor), typeof(CursorTypeConverter) }, |
|||
{ typeof(WindowIcon), typeof(IconTypeConverter) }, |
|||
//{ typeof(FontWeight), typeof(FontWeightConverter) },
|
|||
}; |
|||
|
|||
public static Type GetTypeConverter(Type type) |
|||
{ |
|||
Type converterType; |
|||
|
|||
if (_defaultConverters.TryGetValue(type, out converterType)) |
|||
{ |
|||
return converterType; |
|||
} |
|||
|
|||
//TODO: probably a smarter way to handle types
|
|||
//is it needed ??
|
|||
//Type curType = type;
|
|||
|
|||
//while (curType != null)
|
|||
//{
|
|||
// if (_defaultConverters.TryGetValue(curType, out converterType))
|
|||
// {
|
|||
// if (curType != type)
|
|||
// {
|
|||
// _defaultConverters[curType] = converterType;
|
|||
// }
|
|||
// return converterType;
|
|||
// }
|
|||
// else
|
|||
// {
|
|||
// _defaultConverters[curType] = null;
|
|||
// }
|
|||
// curType = curType.GetTypeInfo().BaseType;
|
|||
//}
|
|||
|
|||
|
|||
|
|||
return null; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,71 @@ |
|||
using Avalonia.Markup.Xaml.Converters; |
|||
using Avalonia.Styling; |
|||
using Portable.Xaml.ComponentModel; |
|||
using System.ComponentModel; |
|||
using System; |
|||
using System.Linq; |
|||
using System.Reflection; |
|||
using avm = Avalonia.Metadata; |
|||
using pm = Portable.Xaml.Markup; |
|||
|
|||
namespace Avalonia.Markup.Xaml.PortableXaml |
|||
{ |
|||
public class AvaloniaMemberAttributeProvider : ICustomAttributeProvider |
|||
{ |
|||
public AvaloniaMemberAttributeProvider(MemberInfo info) |
|||
{ |
|||
_info = info; |
|||
} |
|||
|
|||
public object[] GetCustomAttributes(bool inherit) |
|||
{ |
|||
throw new NotImplementedException(); |
|||
} |
|||
|
|||
public object[] GetCustomAttributes(Type attributeType, bool inherit) |
|||
{ |
|||
Attribute result = null; |
|||
|
|||
if (attributeType == typeof(pm.XamlDeferLoadAttribute)) |
|||
{ |
|||
result = _info.GetCustomAttribute<avm.TemplateContentAttribute>(inherit) |
|||
.ToPortableXaml(); |
|||
} |
|||
else if (attributeType == typeof(pm.AmbientAttribute)) |
|||
{ |
|||
result = _info.GetCustomAttribute<avm.AmbientAttribute>(inherit) |
|||
.ToPortableXaml(); |
|||
} |
|||
else if (attributeType == typeof(pm.DependsOnAttribute)) |
|||
{ |
|||
result = _info.GetCustomAttribute<avm.DependsOnAttribute>(inherit) |
|||
.ToPortableXaml(); |
|||
} |
|||
else if (attributeType == typeof(TypeConverterAttribute) && |
|||
_info.DeclaringType == typeof(Setter) && |
|||
_info.Name == nameof(Setter.Value)) |
|||
{ |
|||
//actually it never comes here looks like if property type is object
|
|||
//Portable.Xaml is not searching for Type Converter
|
|||
result = new TypeConverterAttribute(typeof(SetterValueTypeConverter)); |
|||
} |
|||
|
|||
if (result == null) |
|||
{ |
|||
var attr = _info.GetCustomAttributes(attributeType, inherit); |
|||
return (attr as object[]) ?? attr.ToArray(); |
|||
} |
|||
else |
|||
{ |
|||
return new object[] { result }; |
|||
} |
|||
} |
|||
|
|||
public bool IsDefined(Type attributeType, bool inherit) |
|||
{ |
|||
throw new NotImplementedException(); |
|||
} |
|||
|
|||
private readonly MemberInfo _info; |
|||
} |
|||
} |
|||
@ -0,0 +1,56 @@ |
|||
using System.Collections.Generic; |
|||
using Avalonia.Controls; |
|||
|
|||
namespace Avalonia.Markup.Xaml.PortableXaml |
|||
{ |
|||
internal class AvaloniaNameScope : Portable.Xaml.Markup.INameScope |
|||
{ |
|||
public object Instance { get; set; } |
|||
|
|||
private Dictionary<string, object> _names = new Dictionary<string, object>(); |
|||
|
|||
public object FindName(string name) |
|||
{ |
|||
object result; |
|||
if (_names.TryGetValue(name, out result)) |
|||
return result; |
|||
return null; |
|||
} |
|||
|
|||
public void RegisterName(string name, object scopedElement) |
|||
{ |
|||
if (scopedElement != null) |
|||
_names.Add(name, scopedElement); |
|||
|
|||
//TODO: ???
|
|||
//var control = scopedElement as Control;
|
|||
|
|||
//if (control != null)
|
|||
//{
|
|||
// var nameScope = (Instance as INameScope) ?? control.FindNameScope();
|
|||
|
|||
// if (nameScope != null)
|
|||
// {
|
|||
// nameScope.Register(name, scopedElement);
|
|||
// }
|
|||
//}
|
|||
} |
|||
|
|||
public void UnregisterName(string name) |
|||
{ |
|||
} |
|||
|
|||
public void RegisterOnNameScope(object target) |
|||
{ |
|||
var nameScope = target as INameScope; |
|||
|
|||
if (nameScope != null) |
|||
{ |
|||
foreach (var v in _names) |
|||
{ |
|||
nameScope.Register(v.Key, v.Value); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue