diff --git a/src/Avalonia.Controls/RelativePanel.AttachedProperties.cs b/src/Avalonia.Controls/RelativePanel.AttachedProperties.cs index a42eb6d428..7e67f96152 100644 --- a/src/Avalonia.Controls/RelativePanel.AttachedProperties.cs +++ b/src/Avalonia.Controls/RelativePanel.AttachedProperties.cs @@ -3,7 +3,6 @@ using System.Collections.Generic; using System.ComponentModel; using System.Text; using Avalonia.Layout; -using Avalonia.Markup.Xaml.Converters; namespace Avalonia.Controls { @@ -20,7 +19,7 @@ namespace Avalonia.Controls { AboveProperty.Changed.AddClassHandler(OnAlignPropertiesChanged); AlignBottomWithPanelProperty.Changed.AddClassHandler(OnAlignPropertiesChanged); - AlignBottomWithProperty.Changed.AddClassHandler(OnAlignPropertiesChanged); + AlignBottomWithProperty.Changed.AddClassHandler(OnAlignPropertiesChanged); AlignHorizontalCenterWithPanelProperty.Changed.AddClassHandler(OnAlignPropertiesChanged); AlignHorizontalCenterWithProperty.Changed.AddClassHandler(OnAlignPropertiesChanged); AlignLeftWithPanelProperty.Changed.AddClassHandler(OnAlignPropertiesChanged); @@ -43,8 +42,7 @@ namespace Avalonia.Controls /// /// The RelativePanel.Above XAML attached property value of the specified object. /// (The element to position this element above.) - /// - [TypeConverter(typeof(NameReferenceConverter))] + /// public static object GetAbove(AvaloniaObject obj) { return (object)obj.GetValue(AboveProperty); @@ -60,9 +58,11 @@ namespace Avalonia.Controls obj.SetValue(AboveProperty, value); } + /// /// Identifies the XAML attached property. - /// + /// + [ResolveByName] public static readonly AttachedProperty AboveProperty = AvaloniaProperty.RegisterAttached("Above", typeof(RelativePanel)); @@ -107,8 +107,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.) - /// - [TypeConverter(typeof(NameReferenceConverter))] + /// public static object GetAlignBottomWith(AvaloniaObject obj) { return (object)obj.GetValue(AlignBottomWithProperty); @@ -127,6 +126,7 @@ namespace Avalonia.Controls /// /// Identifies the XAML attached property. /// + [ResolveByName] public static readonly AttachedProperty AlignBottomWithProperty = AvaloniaProperty.RegisterAttached("AlignBottomWith", typeof(RelativePanel)); @@ -170,8 +170,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.) - /// - [TypeConverter(typeof(NameReferenceConverter))] + /// public static object GetAlignHorizontalCenterWith(AvaloniaObject obj) { return (object)obj.GetValue(AlignHorizontalCenterWithProperty); @@ -190,6 +189,7 @@ namespace Avalonia.Controls /// /// Identifies the XAML attached property. /// + [ResolveByName] public static readonly AttachedProperty AlignHorizontalCenterWithProperty = AvaloniaProperty.RegisterAttached("AlignHorizontalCenterWith", typeof(object), typeof(RelativePanel)); @@ -234,8 +234,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.) - /// - [TypeConverter(typeof(NameReferenceConverter))] + /// public static object GetAlignLeftWith(AvaloniaObject obj) { return (object)obj.GetValue(AlignLeftWithProperty); @@ -254,6 +253,7 @@ namespace Avalonia.Controls /// /// Identifies the XAML attached property. /// + [ResolveByName] public static readonly AttachedProperty AlignLeftWithProperty = AvaloniaProperty.RegisterAttached("AlignLeftWith"); @@ -298,8 +298,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.) - /// - [TypeConverter(typeof(NameReferenceConverter))] + /// public static object GetAlignRightWith(AvaloniaObject obj) { return (object)obj.GetValue(AlignRightWithProperty); @@ -318,6 +317,7 @@ namespace Avalonia.Controls /// /// Identifies the XAML attached property. /// + [ResolveByName] public static readonly AttachedProperty AlignRightWithProperty = AvaloniaProperty.RegisterAttached("AlignRightWith"); @@ -358,8 +358,7 @@ namespace Avalonia.Controls /// Gets the value of the RelativePanel.AlignTopWith XAML attached property for the target element. /// /// The object from which the property value is read. - /// The value to set. (The element to align this element's top edge with.) - [TypeConverter(typeof(NameReferenceConverter))] + /// The value to set. (The element to align this element's top edge with.) public static object GetAlignTopWith(AvaloniaObject obj) { return (object)obj.GetValue(AlignTopWithProperty); @@ -378,6 +377,7 @@ namespace Avalonia.Controls /// /// Identifies the XAML attached property. /// + [ResolveByName] public static readonly AttachedProperty AlignTopWithProperty = AvaloniaProperty.RegisterAttached("AlignTopWith"); @@ -418,8 +418,7 @@ namespace Avalonia.Controls /// Gets the value of the RelativePanel.AlignVerticalCenterWith XAML attached property for the target element. /// /// The object from which the property value is read. - /// The value to set. (The element to align this element's vertical center with.) - [TypeConverter(typeof(NameReferenceConverter))] + /// The value to set. (The element to align this element's vertical center with.) public static object GetAlignVerticalCenterWith(AvaloniaObject obj) { return (object)obj.GetValue(AlignVerticalCenterWithProperty); @@ -429,7 +428,8 @@ namespace Avalonia.Controls /// Sets the value of the RelativePanel.AlignVerticalCenterWith XAML attached property for a target element. /// /// The object to which the property value is written. - /// The value to set. (The element to align this element's horizontal center with.) + /// 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,8 +448,7 @@ namespace Avalonia.Controls /// /// The RelativePanel.Below XAML attached property value of the specified object. /// (The element to position this element below.) - /// - [TypeConverter(typeof(NameReferenceConverter))] + /// public static object GetBelow(AvaloniaObject obj) { return (object)obj.GetValue(BelowProperty); @@ -468,6 +467,7 @@ namespace Avalonia.Controls /// /// Identifies the XAML attached property. /// + [ResolveByName] public static readonly AttachedProperty BelowProperty = AvaloniaProperty.RegisterAttached("Below"); @@ -478,8 +478,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.) - /// - [TypeConverter(typeof(NameReferenceConverter))] + /// public static object GetLeftOf(AvaloniaObject obj) { return (object)obj.GetValue(LeftOfProperty); @@ -498,6 +497,7 @@ namespace Avalonia.Controls /// /// Identifies the XAML attached property. /// + [ResolveByName] public static readonly AttachedProperty LeftOfProperty = AvaloniaProperty.RegisterAttached("LeftOf"); @@ -508,8 +508,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.) - /// - [TypeConverter(typeof(NameReferenceConverter))] + /// public static object GetRightOf(AvaloniaObject obj) { return (object)obj.GetValue(RightOfProperty); @@ -528,6 +527,7 @@ namespace Avalonia.Controls /// /// Identifies the XAML attached property. /// + [ResolveByName] public static readonly AttachedProperty RightOfProperty = AvaloniaProperty.RegisterAttached("RightOf"); } diff --git a/src/Avalonia.Controls/ResolveByNameAttribute.cs b/src/Avalonia.Controls/ResolveByNameAttribute.cs new file mode 100644 index 0000000000..a00e3f8a1b --- /dev/null +++ b/src/Avalonia.Controls/ResolveByNameAttribute.cs @@ -0,0 +1,9 @@ +using System; + +namespace Avalonia.Controls +{ + public class ResolveByNameAttribute : Attribute + { + + } +} diff --git a/src/Markup/Avalonia.Markup.Xaml/Avalonia.Markup.Xaml.csproj b/src/Markup/Avalonia.Markup.Xaml/Avalonia.Markup.Xaml.csproj index 35e801e5ce..dbcca28480 100644 --- a/src/Markup/Avalonia.Markup.Xaml/Avalonia.Markup.Xaml.csproj +++ b/src/Markup/Avalonia.Markup.Xaml/Avalonia.Markup.Xaml.csproj @@ -26,6 +26,7 @@ + diff --git a/src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/ResolveByNameExtension.cs b/src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/ResolveByNameExtension.cs new file mode 100644 index 0000000000..3698bb3faa --- /dev/null +++ b/src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/ResolveByNameExtension.cs @@ -0,0 +1,35 @@ +using System; +using Avalonia.Controls; + +namespace Avalonia.Markup.Xaml.MarkupExtensions +{ + public class ResolveByNameExtension + { + public string Name { get; set; } + + public object ProvideValue(IServiceProvider serviceProvider) + { + var namescope = serviceProvider.GetService(); + var provideValueTarget = serviceProvider.GetService(); + + var value = namescope.FindAsync(Name); + + if(value.IsCompleted) + { + return value.GetResult(); + } + else + { + value.OnCompleted(() => + { + if(provideValueTarget is AvaloniaObject ao) + { + ao.SetValue(provideValueTarget.TargetProperty as AvaloniaProperty, value); + } + }); + + return null; + } + } + } +} diff --git a/src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/Transformers/AvaloniaXamlIlResolveByNameMarkupExtensionReplacer.cs b/src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/Transformers/AvaloniaXamlIlResolveByNameMarkupExtensionReplacer.cs new file mode 100644 index 0000000000..2323045ffd --- /dev/null +++ b/src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/Transformers/AvaloniaXamlIlResolveByNameMarkupExtensionReplacer.cs @@ -0,0 +1,30 @@ +using System.Linq; +using XamlX.Ast; +using XamlX.Transform; + +namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers +{ + class AvaloniaXamlIlResolveByNameMarkupExtensionReplacer : IXamlAstTransformer + { + public IXamlAstNode Transform(AstTransformationContext context, IXamlAstNode node) + { + if (node is XamlAstXamlPropertyValueNode propertyValueNode) + { + foreach(var attribute in propertyValueNode.Property.GetClrProperty().CustomAttributes) + { + if (attribute.Type.FullName == "Avalonia.Controls.ResolveByNameAttribute") + { + if (propertyValueNode.Values.Count == 1 && + propertyValueNode.Values.First() is XamlAstTextNode) + { + //propertyValueNode.Values[0] = new XamlMarkupExtensionNode(); + } + break; + } + } + } + + return node; + } + } +}