diff --git a/src/Markup/Avalonia.Markup.Xaml/PortableXaml/AvaloniaXamlSchemaContext.cs b/src/Markup/Avalonia.Markup.Xaml/PortableXaml/AvaloniaXamlSchemaContext.cs index b1638d858f..85731abf37 100644 --- a/src/Markup/Avalonia.Markup.Xaml/PortableXaml/AvaloniaXamlSchemaContext.cs +++ b/src/Markup/Avalonia.Markup.Xaml/PortableXaml/AvaloniaXamlSchemaContext.cs @@ -157,11 +157,10 @@ namespace Avalonia.Markup.Xaml.PortableXaml return BindingXamlType.Create(type, this); } - //TODO: do we need it ??? - //if (type.FullName.StartsWith("Avalonia.")) - //{ - // return new AvaloniaXamlType(type, this); - //} + if (typeof(AvaloniaObject).GetTypeInfo().IsAssignableFrom(type.GetTypeInfo())) + { + return new AvaloniaXamlType(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 61a29d3d78..56c0213d81 100644 --- a/src/Markup/Avalonia.Markup.Xaml/PortableXaml/AvaloniaXamlType.cs +++ b/src/Markup/Avalonia.Markup.Xaml/PortableXaml/AvaloniaXamlType.cs @@ -21,26 +21,47 @@ namespace Avalonia.Markup.Xaml.PortableXaml base(underlyingType, schemaContext) { } + + protected override XamlMember LookupMember(string name, bool skipReadOnlyCheck) + { + var m = base.LookupMember(name, skipReadOnlyCheck); + + if (m == null) + { + //so far Portable.xaml haven't found the member/property + //but what if we have AvaloniaProperty + //without setter and/or without getter + //let's try to find the AvaloniaProperty as a fallback + var avProp = AvaloniaPropertyRegistry.Instance.FindRegistered(UnderlyingType, name); + + if (avProp != null && !(skipReadOnlyCheck && avProp.IsReadOnly)) + { + m = new AvaloniaPropertyXamlMember(avProp, this); + } + } + + return m; + } } - public class BindingXamlType : AvaloniaXamlType + public class BindingXamlType : XamlType { public static BindingXamlType Create(Type type, XamlSchemaContext schemaContext) { if (type == typeof(Binding)) { - //in xmal we need to use the extension + //in xaml we need to use the extension type = typeof(BindingExtension); } return new BindingXamlType(type, schemaContext); } - private static HashSet _notAssignable = - new HashSet() - { - typeof (IXmlSerializable) - }; + private static List _notAssignable = + new List + { + typeof (IXmlSerializable) + }; private BindingXamlType(Type underlyingType, XamlSchemaContext schemaContext) : base(underlyingType, schemaContext) @@ -49,37 +70,25 @@ namespace Avalonia.Markup.Xaml.PortableXaml public override bool CanAssignTo(XamlType xamlType) { - if (_notAssignable.Contains(xamlType.UnderlyingType)) - { - return false; - } - - return true; - } - - protected override XamlMember LookupAliasedProperty(XamlDirective directive) - { - return base.LookupAliasedProperty(directive); - } - - protected override bool LookupIsMarkupExtension() - { - return base.LookupIsMarkupExtension(); + return !_notAssignable.Contains(xamlType.UnderlyingType); } } public class PropertyXamlMember : XamlMember { + public PropertyXamlMember(PropertyInfo propertyInfo, XamlSchemaContext schemaContext) + : base(propertyInfo, schemaContext) + { + } + protected PropertyXamlMember(string attachablePropertyName, MethodInfo getter, MethodInfo setter, XamlSchemaContext schemaContext) : base(attachablePropertyName, getter, setter, schemaContext) { } - public PropertyXamlMember( - PropertyInfo propertyInfo, - XamlSchemaContext schemaContext) : - base(propertyInfo, schemaContext) + protected PropertyXamlMember(string name, XamlType declaringType, bool isAttachable) + : base(name, declaringType, isAttachable) { } @@ -122,19 +131,29 @@ namespace Avalonia.Markup.Xaml.PortableXaml protected override XamlType LookupType() { - var pi = UnderlyingMember as PropertyInfo; - if (pi != null) + var propType = GetPropertyType(); + + if (propType != null) { - if (pi.PropertyType == typeof(IEnumerable)) + if (propType == typeof(IEnumerable)) { + //TODO: Portable.xaml is not handling well IEnumerable //let's threat IEnumerable property as list - return DeclaringType.SchemaContext.GetXamlType(typeof(IList)); + //revisit this when smarter solution is found + propType = typeof(IList); } + + return DeclaringType.SchemaContext.GetXamlType(propType); } return base.LookupType(); } + protected virtual Type GetPropertyType() + { + return (UnderlyingMember as PropertyInfo)?.PropertyType; + } + private IList _dependsOn; protected override IList LookupDependsOn() @@ -246,18 +265,10 @@ namespace Avalonia.Markup.Xaml.PortableXaml { private bool? _assignBinding; - public bool AssignBinding => (bool)(_assignBinding ?? (_assignBinding = UnderlyingMember.GetCustomAttribute() != null)); + public bool AssignBinding => (bool)(_assignBinding ?? (_assignBinding = UnderlyingMember?.GetCustomAttribute() != null)); public AvaloniaProperty Property { get; } - protected AvaloniaPropertyXamlMember(AvaloniaProperty property, - string attachablePropertyName, - MethodInfo getter, MethodInfo setter, XamlSchemaContext schemaContext) - : base(attachablePropertyName, getter, setter, schemaContext) - { - Property = property; - } - public AvaloniaPropertyXamlMember(AvaloniaProperty property, PropertyInfo propertyInfo, XamlSchemaContext schemaContext) : @@ -266,6 +277,20 @@ namespace Avalonia.Markup.Xaml.PortableXaml Property = property; } + public AvaloniaPropertyXamlMember(AvaloniaProperty property, XamlType type) : + base(property.Name, type, false) + { + Property = property; + } + + protected AvaloniaPropertyXamlMember(AvaloniaProperty property, + string attachablePropertyName, + MethodInfo getter, MethodInfo setter, XamlSchemaContext schemaContext) + : base(attachablePropertyName, getter, setter, schemaContext) + { + Property = property; + } + protected override XamlMemberInvoker LookupInvoker() { return new AvaloniaPropertyInvoker(this); @@ -276,6 +301,11 @@ namespace Avalonia.Markup.Xaml.PortableXaml return Property.IsReadOnly; } + protected override Type GetPropertyType() + { + return Property.PropertyType; + } + private class AvaloniaPropertyInvoker : XamlMemberInvoker { public AvaloniaPropertyInvoker(XamlMember member) : base(member) @@ -342,22 +372,12 @@ namespace Avalonia.Markup.Xaml.PortableXaml public class AvaloniaAttachedPropertyXamlMember : AvaloniaPropertyXamlMember { - private MethodInfo _setter; - public AvaloniaAttachedPropertyXamlMember(AvaloniaProperty property, string attachablePropertyName, MethodInfo getter, MethodInfo setter, XamlSchemaContext schemaContext) : base(property, attachablePropertyName, getter, setter, schemaContext) { - _setter = setter; - } - - protected override MethodInfo LookupUnderlyingSetter() - { - return base.LookupUnderlyingSetter(); - //TODO: investigate don't call base stack overflow - return _setter; } } } \ No newline at end of file