diff --git a/src/Avalonia.Controls/RelativePanel.AttachedProperties.cs b/src/Avalonia.Controls/RelativePanel.AttachedProperties.cs index 7e67f96152..50d2ccbc73 100644 --- a/src/Avalonia.Controls/RelativePanel.AttachedProperties.cs +++ b/src/Avalonia.Controls/RelativePanel.AttachedProperties.cs @@ -43,6 +43,7 @@ namespace Avalonia.Controls /// The RelativePanel.Above XAML attached property value of the specified object. /// (The element to position this element above.) /// + [ResolveByName] public static object GetAbove(AvaloniaObject obj) { return (object)obj.GetValue(AboveProperty); @@ -62,7 +63,7 @@ namespace Avalonia.Controls /// /// Identifies the XAML attached property. /// - [ResolveByName] + public static readonly AttachedProperty AboveProperty = AvaloniaProperty.RegisterAttached("Above", typeof(RelativePanel)); @@ -108,6 +109,7 @@ namespace Avalonia.Controls /// The RelativePanel.AlignBottomWith XAML attached property value of the specified object. /// (The element to align this element's bottom edge with.) /// + [ResolveByName] public static object GetAlignBottomWith(AvaloniaObject obj) { return (object)obj.GetValue(AlignBottomWithProperty); @@ -126,7 +128,7 @@ namespace Avalonia.Controls /// /// Identifies the XAML attached property. /// - [ResolveByName] + public static readonly AttachedProperty AlignBottomWithProperty = AvaloniaProperty.RegisterAttached("AlignBottomWith", typeof(RelativePanel)); @@ -171,6 +173,7 @@ namespace Avalonia.Controls /// The RelativePanel.AlignHorizontalCenterWith XAML attached property value of the /// specified object. (The element to align this element's horizontal center with.) /// + [ResolveByName] public static object GetAlignHorizontalCenterWith(AvaloniaObject obj) { return (object)obj.GetValue(AlignHorizontalCenterWithProperty); @@ -189,7 +192,7 @@ namespace Avalonia.Controls /// /// Identifies the XAML attached property. /// - [ResolveByName] + public static readonly AttachedProperty AlignHorizontalCenterWithProperty = AvaloniaProperty.RegisterAttached("AlignHorizontalCenterWith", typeof(object), typeof(RelativePanel)); @@ -235,6 +238,7 @@ namespace Avalonia.Controls /// The RelativePanel.AlignLeftWith XAML attached property value of the specified /// object. (The element to align this element's left edge with.) /// + [ResolveByName] public static object GetAlignLeftWith(AvaloniaObject obj) { return (object)obj.GetValue(AlignLeftWithProperty); @@ -253,7 +257,7 @@ namespace Avalonia.Controls /// /// Identifies the XAML attached property. /// - [ResolveByName] + public static readonly AttachedProperty AlignLeftWithProperty = AvaloniaProperty.RegisterAttached("AlignLeftWith"); @@ -299,6 +303,7 @@ namespace Avalonia.Controls /// The RelativePanel.AlignRightWith XAML attached property value of the specified /// object. (The element to align this element's right edge with.) /// + [ResolveByName] public static object GetAlignRightWith(AvaloniaObject obj) { return (object)obj.GetValue(AlignRightWithProperty); @@ -317,7 +322,7 @@ namespace Avalonia.Controls /// /// Identifies the XAML attached property. /// - [ResolveByName] + public static readonly AttachedProperty AlignRightWithProperty = AvaloniaProperty.RegisterAttached("AlignRightWith"); @@ -359,6 +364,7 @@ namespace Avalonia.Controls /// /// The object from which the property value is read. /// The value to set. (The element to align this element's top edge with.) + [ResolveByName] public static object GetAlignTopWith(AvaloniaObject obj) { return (object)obj.GetValue(AlignTopWithProperty); @@ -377,7 +383,7 @@ namespace Avalonia.Controls /// /// Identifies the XAML attached property. /// - [ResolveByName] + public static readonly AttachedProperty AlignTopWithProperty = AvaloniaProperty.RegisterAttached("AlignTopWith"); @@ -419,6 +425,7 @@ namespace Avalonia.Controls /// /// The object from which the property value is read. /// The value to set. (The element to align this element's vertical center with.) + [ResolveByName] public static object GetAlignVerticalCenterWith(AvaloniaObject obj) { return (object)obj.GetValue(AlignVerticalCenterWithProperty); @@ -429,7 +436,7 @@ namespace Avalonia.Controls /// /// The object to which the property value is written. /// The value to set. (The element to align this element's horizontal center with.) - [ResolveByName] + public static void SetAlignVerticalCenterWith(AvaloniaObject obj, object value) { obj.SetValue(AlignVerticalCenterWithProperty, value); @@ -448,7 +455,8 @@ namespace Avalonia.Controls /// /// The RelativePanel.Below XAML attached property value of the specified object. /// (The element to position this element below.) - /// + /// + [ResolveByName] public static object GetBelow(AvaloniaObject obj) { return (object)obj.GetValue(BelowProperty); @@ -459,6 +467,7 @@ namespace Avalonia.Controls /// /// The object to which the property value is written. /// The value to set. (The element to position this element below.) + public static void SetBelow(AvaloniaObject obj, object value) { obj.SetValue(BelowProperty, value); @@ -467,7 +476,7 @@ namespace Avalonia.Controls /// /// Identifies the XAML attached property. /// - [ResolveByName] + public static readonly AttachedProperty BelowProperty = AvaloniaProperty.RegisterAttached("Below"); @@ -479,6 +488,7 @@ namespace Avalonia.Controls /// The RelativePanel.LeftOf XAML attached property value of the specified object. /// (The element to position this element to the left of.) /// + [ResolveByName] public static object GetLeftOf(AvaloniaObject obj) { return (object)obj.GetValue(LeftOfProperty); @@ -497,7 +507,7 @@ namespace Avalonia.Controls /// /// Identifies the XAML attached property. /// - [ResolveByName] + public static readonly AttachedProperty LeftOfProperty = AvaloniaProperty.RegisterAttached("LeftOf"); @@ -509,6 +519,7 @@ namespace Avalonia.Controls /// The RelativePanel.RightOf XAML attached property value of the specified object. /// (The element to position this element to the right of.) /// + [ResolveByName] public static object GetRightOf(AvaloniaObject obj) { return (object)obj.GetValue(RightOfProperty); @@ -527,7 +538,7 @@ namespace Avalonia.Controls /// /// Identifies the XAML attached property. /// - [ResolveByName] + public static readonly AttachedProperty RightOfProperty = AvaloniaProperty.RegisterAttached("RightOf"); } diff --git a/src/Avalonia.Controls/RelativePanel.cs b/src/Avalonia.Controls/RelativePanel.cs index f1989de570..61e69bf766 100644 --- a/src/Avalonia.Controls/RelativePanel.cs +++ b/src/Avalonia.Controls/RelativePanel.cs @@ -410,6 +410,7 @@ namespace Avalonia.Controls private Layoutable GetDependencyElement(AvaloniaProperty property, AvaloniaObject child) { var dependency = child.GetValue(property); + if (dependency == null) return null; if (dependency is Layoutable) @@ -419,6 +420,7 @@ namespace Avalonia.Controls throw new ArgumentException(string.Format("RelativePanel error: Element does not exist in the current context", property.Name)); } + return null; throw new ArgumentException("RelativePanel error: Value must be of type ILayoutable"); } } diff --git a/src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/ResolveByNameExtension.cs b/src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/ResolveByNameExtension.cs index 3698bb3faa..33263b6a27 100644 --- a/src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/ResolveByNameExtension.cs +++ b/src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/ResolveByNameExtension.cs @@ -4,8 +4,13 @@ using Avalonia.Controls; namespace Avalonia.Markup.Xaml.MarkupExtensions { public class ResolveByNameExtension - { - public string Name { get; set; } + { + public ResolveByNameExtension(string name) + { + Name = name; + } + + public string Name { get; } public object ProvideValue(IServiceProvider serviceProvider) { diff --git a/src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/Transformers/AvaloniaXamlIlResolveByNameMarkupExtensionReplacer.cs b/src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/Transformers/AvaloniaXamlIlResolveByNameMarkupExtensionReplacer.cs index 4614d4b6a1..f550f82972 100644 --- a/src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/Transformers/AvaloniaXamlIlResolveByNameMarkupExtensionReplacer.cs +++ b/src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/Transformers/AvaloniaXamlIlResolveByNameMarkupExtensionReplacer.cs @@ -1,6 +1,9 @@ -using System.Linq; +using System.Collections; +using System.Collections.Generic; +using System.Linq; using XamlX.Ast; using XamlX.Transform; +using XamlX.TypeSystem; namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers { @@ -10,24 +13,35 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers { if (node is XamlAstXamlPropertyValueNode propertyValueNode) { - foreach(var attribute in propertyValueNode.Property.GetClrProperty().CustomAttributes) + + IEnumerable attributes = propertyValueNode.Property.GetClrProperty().CustomAttributes; + + if (propertyValueNode.Property is XamlAstClrProperty referenceNode && + referenceNode.Getter != null) + { + attributes = attributes.Concat(referenceNode.Getter.CustomAttributes); + } + + foreach (var attribute in attributes) { if (attribute.Type.FullName == "Avalonia.Controls.ResolveByNameAttribute") { if (propertyValueNode.Values.Count == 1 && propertyValueNode.Values.First() is XamlAstTextNode) { - propertyValueNode.Values[0] = - new XamlAstObjectNode( + if (XamlTransformHelpers.TryConvertMarkupExtension(context, new XamlAstObjectNode( propertyValueNode.Values[0], new XamlAstClrTypeReference(propertyValueNode.Values[0], context.GetAvaloniaTypes().ResolveByNameExtension, true)) - { - Arguments = new System.Collections.Generic.List + { + Arguments = new System.Collections.Generic.List { propertyValueNode.Values[0] } - }; + }, out var extensionNode)) + { + propertyValueNode.Values[0] = extensionNode; + } } break; } diff --git a/src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/Transformers/AvaloniaXamlIlTransformInstanceAttachedProperties.cs b/src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/Transformers/AvaloniaXamlIlTransformInstanceAttachedProperties.cs index 8e194e9385..d78ceeb918 100644 --- a/src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/Transformers/AvaloniaXamlIlTransformInstanceAttachedProperties.cs +++ b/src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/Transformers/AvaloniaXamlIlTransformInstanceAttachedProperties.cs @@ -174,6 +174,9 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers other is GetterMethod m && m.Name == Name && m.DeclaringType.Equals(DeclaringType); public IXamlType ReturnType => Parent.PropertyType; public IReadOnlyList Parameters { get; } + + public IReadOnlyList CustomAttributes => DeclaringType.CustomAttributes; + public void EmitCall(IXamlILEmitter emitter) { var method = Parent._avaloniaObject diff --git a/src/Markup/Avalonia.Markup.Xaml/XamlIl/xamlil.github b/src/Markup/Avalonia.Markup.Xaml/XamlIl/xamlil.github index 0028377ce7..7b8b3013bd 160000 --- a/src/Markup/Avalonia.Markup.Xaml/XamlIl/xamlil.github +++ b/src/Markup/Avalonia.Markup.Xaml/XamlIl/xamlil.github @@ -1 +1 @@ -Subproject commit 0028377ce7c7dc21f9fe71b45f62a95991b1ab58 +Subproject commit 7b8b3013bd42e1992838a525c991f44191da55be