diff --git a/external/XamlX b/external/XamlX
index ab84721302d..cbfec32876a 160000
--- a/external/XamlX
+++ b/external/XamlX
@@ -1 +1 @@
-Subproject commit ab84721302d6ed2b8b65315f3c54217693640348
+Subproject commit cbfec32876a79e855bd49da034214bbf2bf35b13
diff --git a/src/Avalonia.Base/Data/AssignBindingAttribute.cs b/src/Avalonia.Base/Data/AssignBindingAttribute.cs
index 15bd32c7c21..45120157ad9 100644
--- a/src/Avalonia.Base/Data/AssignBindingAttribute.cs
+++ b/src/Avalonia.Base/Data/AssignBindingAttribute.cs
@@ -10,7 +10,7 @@ namespace Avalonia.Data
/// Applying this attribute to a property indicates that the binding should be assigned to
/// the property rather than bound.
///
- [AttributeUsage(AttributeTargets.Property)]
+ [AttributeUsage(AttributeTargets.Property | AttributeTargets.Method)]
public sealed class AssignBindingAttribute : Attribute
{
}
diff --git a/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/XamlIlAvaloniaPropertyHelper.cs b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/XamlIlAvaloniaPropertyHelper.cs
index 7fd8d987b9f..0d4b6eceeff 100644
--- a/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/XamlIlAvaloniaPropertyHelper.cs
+++ b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/XamlIlAvaloniaPropertyHelper.cs
@@ -204,12 +204,11 @@ class XamlIlAvaloniaProperty : XamlAstClrProperty, IXamlIlAvaloniaProperty
public IXamlField AvaloniaProperty { get; }
public XamlIlAvaloniaProperty(XamlAstClrProperty original, IXamlField field,
AvaloniaXamlIlWellKnownTypes types)
- :base(original, original.Name, original.DeclaringType, original.Getter, original.Setters)
+ :base(original, original.Name, original.DeclaringType, original.Getter, original.Setters, original.CustomAttributes)
{
var assignBinding = original.CustomAttributes.Any(ca => ca.Type.Equals(types.AssignBindingAttribute));
AvaloniaProperty = field;
- CustomAttributes = original.CustomAttributes;
if (!assignBinding)
Setters.Insert(0, new BindingSetter(types, original.DeclaringType, field));
@@ -459,7 +458,7 @@ sealed class XamlIlAvaloniaClassProperty : XamlAstClrProperty,
public XamlIlAvaloniaClassProperty(AvaloniaXamlIlWellKnownTypes types,
string className,
- IXamlLineInfo lineInfo) : base(lineInfo, className, types.Classes, null, null, null)
+ IXamlLineInfo lineInfo) : base(lineInfo, className, types.Classes, null)
{
Parameters = [types.XamlIlTypes.String];
_method = types.GetClassProperty;
diff --git a/tests/Avalonia.Markup.Xaml.UnitTests/Xaml/AssignBindingTests.cs b/tests/Avalonia.Markup.Xaml.UnitTests/Xaml/AssignBindingTests.cs
new file mode 100644
index 00000000000..114b626e639
--- /dev/null
+++ b/tests/Avalonia.Markup.Xaml.UnitTests/Xaml/AssignBindingTests.cs
@@ -0,0 +1,62 @@
+#nullable enable
+
+using Avalonia.Controls;
+using Avalonia.Data;
+using Avalonia.UnitTests;
+using Xunit;
+
+namespace Avalonia.Markup.Xaml.UnitTests.Xaml;
+
+public class AssignBindingTests : XamlTestBase
+{
+ [Fact]
+ public void AssignBinding_Works_With_Clr_Property()
+ {
+ using var app = UnitTestApplication.Start(TestServices.StyledWindow);
+
+ var control = (AssignBindingTestControl)AvaloniaRuntimeXamlLoader.Load(
+ """
+
+ """);
+
+ Assert.NotNull(control.ClrBinding);
+ }
+
+ [Fact]
+ public void AssignBinding_Works_With_AttachedProperty()
+ {
+ using var app = UnitTestApplication.Start(TestServices.StyledWindow);
+
+ var control = (Control)AvaloniaRuntimeXamlLoader.Load(
+ """
+
+ """);
+
+ var binding = AssignBindingTestControl.GetAttachedBinding(control);
+ Assert.NotNull(binding);
+ }
+}
+
+public sealed class AssignBindingTestControl : Control
+{
+ [AssignBinding]
+ public IBinding? ClrBinding { get; set; }
+
+ public static readonly AttachedProperty AttachedBindingProperty =
+ AvaloniaProperty.RegisterAttached("AttachedBinding");
+
+ [AssignBinding]
+ public static IBinding? GetAttachedBinding(Control obj)
+ => obj.GetValue(AttachedBindingProperty);
+
+ public static void SetAttachedBinding(Control obj, IBinding? value)
+ => obj.SetValue(AttachedBindingProperty, value);
+}