浏览代码

Pass both owner and host type to AvaloniaProperty.

For non-attached properties these will be the same. For attached properties the metadata needs to be registered on the host, but the `Owner` property needs to be set to the owner, not the host.
Steven Kirk 2 年之前
父节点
当前提交
00d077a634

+ 3 - 1
src/Avalonia.Base/AttachedProperty.cs

@@ -13,16 +13,18 @@ namespace Avalonia
         /// </summary>
         /// <param name="name">The name of the property.</param>
         /// <param name="ownerType">The class that is registering the property.</param>
+        /// <param name="hostType">The class that the property being is registered on.</param>
         /// <param name="metadata">The property metadata.</param>
         /// <param name="inherits">Whether the property inherits its value.</param>
         /// <param name="validate">A value validation callback.</param>
         public AttachedProperty(
             string name,
             Type ownerType,
+            Type hostType,
             StyledPropertyMetadata<TValue> metadata,
             bool inherits = false,
             Func<TValue, bool>? validate = null)
-            : base(name, ownerType, metadata, inherits, validate)
+            : base(name, ownerType, hostType, metadata, inherits, validate)
         {
             IsAttached = true;
         }

+ 8 - 4
src/Avalonia.Base/AvaloniaProperty.cs

@@ -39,12 +39,14 @@ namespace Avalonia
         /// <param name="name">The name of the property.</param>
         /// <param name="valueType">The type of the property's value.</param>
         /// <param name="ownerType">The type of the class that registers the property.</param>
+        /// <param name="hostType">The class that the property being is registered on.</param>
         /// <param name="metadata">The property metadata.</param>
         /// <param name="notifying">A <see cref="Notifying"/> callback.</param>
         protected AvaloniaProperty(
             string name,
             Type valueType,
             Type ownerType,
+            Type hostType,
             AvaloniaPropertyMetadata metadata,
             Action<AvaloniaObject, bool>? notifying = null)
         {
@@ -63,9 +65,9 @@ namespace Avalonia
             Notifying = notifying;
             Id = s_nextId++;
 
-            _metadata.Add(ownerType, metadata ?? throw new ArgumentNullException(nameof(metadata)));
+            _metadata.Add(hostType, metadata ?? throw new ArgumentNullException(nameof(metadata)));
             _defaultMetadata = metadata.GenerateTypeSafeMetadata();
-            _singleMetadata = new(ownerType, metadata);
+            _singleMetadata = new(hostType, metadata);
         }
 
         /// <summary>
@@ -255,6 +257,7 @@ namespace Avalonia
             var result = new StyledProperty<TValue>(
                 name,
                 typeof(TOwner),
+                typeof(TOwner),
                 metadata,
                 inherits,
                 validate);
@@ -301,6 +304,7 @@ namespace Avalonia
             var result = new StyledProperty<TValue>(
                 name,
                 typeof(TOwner),
+                typeof(TOwner),
                 metadata,
                 inherits,
                 validate,
@@ -338,7 +342,7 @@ namespace Avalonia
                 defaultBindingMode: defaultBindingMode,
                 coerce: coerce);
 
-            var result = new AttachedProperty<TValue>(name, typeof(THost), metadata, inherits, validate);
+            var result = new AttachedProperty<TValue>(name, typeof(TOwner), typeof(THost), metadata, inherits, validate);
             var registry = AvaloniaPropertyRegistry.Instance;
             registry.Register(typeof(TOwner), result);
             registry.RegisterAttached(typeof(THost), result);
@@ -375,7 +379,7 @@ namespace Avalonia
                 defaultBindingMode: defaultBindingMode,
                 coerce: coerce);
 
-            var result = new AttachedProperty<TValue>(name, ownerType, metadata, inherits, validate);
+            var result = new AttachedProperty<TValue>(name, ownerType, typeof(THost), metadata, inherits, validate);
             var registry = AvaloniaPropertyRegistry.Instance;
             registry.Register(ownerType, result);
             registry.RegisterAttached(typeof(THost), result);

+ 3 - 1
src/Avalonia.Base/AvaloniaProperty`1.cs

@@ -19,14 +19,16 @@ namespace Avalonia
         /// </summary>
         /// <param name="name">The name of the property.</param>
         /// <param name="ownerType">The type of the class that registers the property.</param>
+        /// <param name="hostType">The class that the property being is registered on.</param>
         /// <param name="metadata">The property metadata.</param>
         /// <param name="notifying">A <see cref="AvaloniaProperty.Notifying"/> callback.</param>
         protected AvaloniaProperty(
             string name,
             Type ownerType,
+            Type hostType,
             AvaloniaPropertyMetadata metadata,
             Action<AvaloniaObject, bool>? notifying = null)
-            : base(name, typeof(TValue), ownerType, metadata, notifying)
+            : base(name, typeof(TValue), ownerType, hostType, metadata, notifying)
         {
             _changed = new LightweightSubject<AvaloniaPropertyChangedEventArgs<TValue>>();
         }

+ 1 - 1
src/Avalonia.Base/DirectPropertyBase.cs

@@ -24,7 +24,7 @@ namespace Avalonia
             string name,
             Type ownerType,
             AvaloniaPropertyMetadata metadata)
-            : base(name, ownerType, metadata)
+            : base(name, ownerType, ownerType, metadata)
         {
             Owner = ownerType;
         }

+ 3 - 1
src/Avalonia.Base/StyledProperty.cs

@@ -16,6 +16,7 @@ namespace Avalonia
         /// </summary>
         /// <param name="name">The name of the property.</param>
         /// <param name="ownerType">The type of the class that registers the property.</param>
+        /// <param name="hostType">The class that the property being is registered on.</param>
         /// <param name="metadata">The property metadata.</param>
         /// <param name="inherits">Whether the property inherits its value.</param>
         /// <param name="validate">
@@ -26,11 +27,12 @@ namespace Avalonia
         public StyledProperty(
             string name,
             Type ownerType,
+            Type hostType,
             StyledPropertyMetadata<TValue> metadata,
             bool inherits = false,
             Func<TValue, bool>? validate = null,
             Action<AvaloniaObject, bool>? notifying = null)
-                : base(name, ownerType, metadata, notifying)
+                : base(name, ownerType, hostType, metadata, notifying)
         {
             Inherits = inherits;
             ValidateValue = validate;

+ 2 - 0
tests/Avalonia.Base.UnitTests/AttachedPropertyTests.cs

@@ -1,3 +1,4 @@
+using Avalonia.Controls;
 using Xunit;
 
 namespace Avalonia.Base.UnitTests
@@ -10,6 +11,7 @@ namespace Avalonia.Base.UnitTests
             var property = new AttachedProperty<string>(
                 "Foo",
                 typeof(Class1),
+                typeof(Control),
                 new StyledPropertyMetadata<string>());
 
             Assert.True(property.IsAttached);

+ 1 - 0
tests/Avalonia.Base.UnitTests/AvaloniaObjectTests_Validation.cs

@@ -15,6 +15,7 @@ namespace Avalonia.Base.UnitTests
                 new StyledProperty<int>(
                     "BadDefault",
                     typeof(Class1),
+                    typeof(Class1),
                     new StyledPropertyMetadata<int>(101),
                     validate: Class1.ValidateFoo));
         }

+ 1 - 1
tests/Avalonia.Base.UnitTests/AvaloniaPropertyRegistryTests.cs

@@ -22,7 +22,7 @@ namespace Avalonia.Base.UnitTests
         {
             var registry = new AvaloniaPropertyRegistry();
             var metadata = new StyledPropertyMetadata<int>();
-            var property = new AttachedProperty<int>("test", typeof(object), metadata, true);
+            var property = new AttachedProperty<int>("test", typeof(object), typeof(object), metadata, true);
             registry.Register(typeof(object), property);
             registry.RegisterAttached(typeof(AvaloniaPropertyRegistryTests), property);
             property.AddOwner<Class4>();

+ 1 - 1
tests/Avalonia.Base.UnitTests/AvaloniaPropertyTests.cs

@@ -157,7 +157,7 @@ namespace Avalonia.Base.UnitTests
         private class TestProperty<TValue> : AvaloniaProperty<TValue>
         {
             public TestProperty(string name, Type ownerType, TestMetadata metadata = null)
-                : base(name, ownerType, metadata ?? new TestMetadata())
+                : base(name, ownerType, ownerType, metadata ?? new TestMetadata())
             {
             }
 

+ 3 - 1
tests/Avalonia.Base.UnitTests/StyledPropertyTests.cs

@@ -9,7 +9,8 @@ namespace Avalonia.Base.UnitTests
         {
             var p1 = new StyledProperty<string>(
                 "p1", 
-                typeof(Class1), 
+                typeof(Class1),
+                typeof(Class1),
                 new StyledPropertyMetadata<string>());
             var p2 = p1.AddOwner<Class2>();
 
@@ -24,6 +25,7 @@ namespace Avalonia.Base.UnitTests
             var p1 = new StyledProperty<string>(
                 "p1",
                 typeof(Class1),
+                typeof(Class1),
                 new StyledPropertyMetadata<string>());
             var p2 = p1.AddOwner<Class2>();
 

+ 1 - 0
tests/Avalonia.Base.UnitTests/Utilities/AvaloniaPropertyDictionaryTests.cs

@@ -18,6 +18,7 @@ namespace Avalonia.Base.UnitTests.Utilities
                 TestProperties[i] = new StyledProperty<string>(
                     $"Test{i}",
                     typeof(AvaloniaPropertyDictionaryTests),
+                    typeof(AvaloniaPropertyDictionaryTests),
                     new StyledPropertyMetadata<string>());
             }