From 18e66f1b60667766d58f89c114e1c83a1918f41d Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Thu, 29 Aug 2024 17:32:33 +0300 Subject: [PATCH] feat: Implement CreateDefaultValueCallback and PropertyMetadata factory methods --- .../Given_DependencyProperty.cs | 31 ++++++++++++- .../Microsoft.UI.Xaml/PropertyMetadata.cs | 39 +---------------- src/Uno.UI/UI/Xaml/DependencyProperty.cs | 6 ++- .../UI/Xaml/FrameworkPropertyMetadata.cs | 15 ++++++- src/Uno.UI/UI/Xaml/PropertyMetadata.cs | 43 ++++++++++++++++++- 5 files changed, 90 insertions(+), 44 deletions(-) diff --git a/src/Uno.UI.RuntimeTests/Tests/Windows_UI_Xaml/Given_DependencyProperty.cs b/src/Uno.UI.RuntimeTests/Tests/Windows_UI_Xaml/Given_DependencyProperty.cs index 5b33a9349a59..4cdf87d9d378 100644 --- a/src/Uno.UI.RuntimeTests/Tests/Windows_UI_Xaml/Given_DependencyProperty.cs +++ b/src/Uno.UI.RuntimeTests/Tests/Windows_UI_Xaml/Given_DependencyProperty.cs @@ -4,8 +4,27 @@ namespace Uno.UI.RuntimeTests.Tests.Windows_UI_Xaml; [TestClass] [RunsOnUIThread] -public class Given_DependencyProperty +public partial class Given_DependencyProperty { + private partial class MyButton : Button + { + private static int _value; + + public int P + { + get => (int)GetValue(PProperty); + set => SetValue(PProperty, value); + } + + public static DependencyProperty PProperty { get; } = DependencyProperty.Register( + nameof(P), + typeof(int), + typeof(MyButton), + PropertyMetadata.Create(createDefaultValueCallback: CreateDefaultValue)); + + private static object CreateDefaultValue() => _value++; + } + [TestMethod] public void When_Unsubscribe_From_PropertyChanges() { @@ -35,4 +54,14 @@ public void When_GetValueUnderPrecedence() Assert.AreEqual(DependencyPropertyValuePrecedences.DefaultValue, actualPrecedence2); } #endif + + [TestMethod] + public void When_CreateDefaultValueCallback() + { + var myButton = new MyButton(); + Assert.AreEqual(0, myButton.P); + Assert.AreEqual(1, myButton.P); + Assert.AreEqual(2, myButton.P); + Assert.AreEqual(3, myButton.P); + } } diff --git a/src/Uno.UI/Generated/3.0.0.0/Microsoft.UI.Xaml/PropertyMetadata.cs b/src/Uno.UI/Generated/3.0.0.0/Microsoft.UI.Xaml/PropertyMetadata.cs index 739187fb07a0..7d84e0aec560 100644 --- a/src/Uno.UI/Generated/3.0.0.0/Microsoft.UI.Xaml/PropertyMetadata.cs +++ b/src/Uno.UI/Generated/3.0.0.0/Microsoft.UI.Xaml/PropertyMetadata.cs @@ -8,16 +8,7 @@ namespace Microsoft.UI.Xaml #endif public partial class PropertyMetadata { -#if __ANDROID__ || __IOS__ || IS_UNIT_TESTS || __WASM__ || __SKIA__ || __NETSTD_REFERENCE__ || __MACOS__ - [global::Uno.NotImplemented("__ANDROID__", "__IOS__", "IS_UNIT_TESTS", "__WASM__", "__SKIA__", "__NETSTD_REFERENCE__", "__MACOS__")] - public global::Microsoft.UI.Xaml.CreateDefaultValueCallback CreateDefaultValueCallback - { - get - { - throw new global::System.NotImplementedException("The member CreateDefaultValueCallback PropertyMetadata.CreateDefaultValueCallback is not implemented. For more information, visit https://aka.platform.uno/notimplemented#m=CreateDefaultValueCallback%20PropertyMetadata.CreateDefaultValueCallback"); - } - } -#endif + // Skipping already declared property CreateDefaultValueCallback // Skipping already declared property DefaultValue // Skipping already declared method Microsoft.UI.Xaml.PropertyMetadata.PropertyMetadata(object) // Forced skipping of method Microsoft.UI.Xaml.PropertyMetadata.PropertyMetadata(object) @@ -25,33 +16,5 @@ public partial class PropertyMetadata // Forced skipping of method Microsoft.UI.Xaml.PropertyMetadata.PropertyMetadata(object, Microsoft.UI.Xaml.PropertyChangedCallback) // Forced skipping of method Microsoft.UI.Xaml.PropertyMetadata.DefaultValue.get // Forced skipping of method Microsoft.UI.Xaml.PropertyMetadata.CreateDefaultValueCallback.get -#if __ANDROID__ || __IOS__ || IS_UNIT_TESTS || __WASM__ || __SKIA__ || __NETSTD_REFERENCE__ || __MACOS__ - [global::Uno.NotImplemented("__ANDROID__", "__IOS__", "IS_UNIT_TESTS", "__WASM__", "__SKIA__", "__NETSTD_REFERENCE__", "__MACOS__")] - public static global::Microsoft.UI.Xaml.PropertyMetadata Create(object defaultValue) - { - throw new global::System.NotImplementedException("The member PropertyMetadata PropertyMetadata.Create(object defaultValue) is not implemented. For more information, visit https://aka.platform.uno/notimplemented#m=PropertyMetadata%20PropertyMetadata.Create%28object%20defaultValue%29"); - } -#endif -#if __ANDROID__ || __IOS__ || IS_UNIT_TESTS || __WASM__ || __SKIA__ || __NETSTD_REFERENCE__ || __MACOS__ - [global::Uno.NotImplemented("__ANDROID__", "__IOS__", "IS_UNIT_TESTS", "__WASM__", "__SKIA__", "__NETSTD_REFERENCE__", "__MACOS__")] - public static global::Microsoft.UI.Xaml.PropertyMetadata Create(object defaultValue, global::Microsoft.UI.Xaml.PropertyChangedCallback propertyChangedCallback) - { - throw new global::System.NotImplementedException("The member PropertyMetadata PropertyMetadata.Create(object defaultValue, PropertyChangedCallback propertyChangedCallback) is not implemented. For more information, visit https://aka.platform.uno/notimplemented#m=PropertyMetadata%20PropertyMetadata.Create%28object%20defaultValue%2C%20PropertyChangedCallback%20propertyChangedCallback%29"); - } -#endif -#if __ANDROID__ || __IOS__ || IS_UNIT_TESTS || __WASM__ || __SKIA__ || __NETSTD_REFERENCE__ || __MACOS__ - [global::Uno.NotImplemented("__ANDROID__", "__IOS__", "IS_UNIT_TESTS", "__WASM__", "__SKIA__", "__NETSTD_REFERENCE__", "__MACOS__")] - public static global::Microsoft.UI.Xaml.PropertyMetadata Create(global::Microsoft.UI.Xaml.CreateDefaultValueCallback createDefaultValueCallback) - { - throw new global::System.NotImplementedException("The member PropertyMetadata PropertyMetadata.Create(CreateDefaultValueCallback createDefaultValueCallback) is not implemented. For more information, visit https://aka.platform.uno/notimplemented#m=PropertyMetadata%20PropertyMetadata.Create%28CreateDefaultValueCallback%20createDefaultValueCallback%29"); - } -#endif -#if __ANDROID__ || __IOS__ || IS_UNIT_TESTS || __WASM__ || __SKIA__ || __NETSTD_REFERENCE__ || __MACOS__ - [global::Uno.NotImplemented("__ANDROID__", "__IOS__", "IS_UNIT_TESTS", "__WASM__", "__SKIA__", "__NETSTD_REFERENCE__", "__MACOS__")] - public static global::Microsoft.UI.Xaml.PropertyMetadata Create(global::Microsoft.UI.Xaml.CreateDefaultValueCallback createDefaultValueCallback, global::Microsoft.UI.Xaml.PropertyChangedCallback propertyChangedCallback) - { - throw new global::System.NotImplementedException("The member PropertyMetadata PropertyMetadata.Create(CreateDefaultValueCallback createDefaultValueCallback, PropertyChangedCallback propertyChangedCallback) is not implemented. For more information, visit https://aka.platform.uno/notimplemented#m=PropertyMetadata%20PropertyMetadata.Create%28CreateDefaultValueCallback%20createDefaultValueCallback%2C%20PropertyChangedCallback%20propertyChangedCallback%29"); - } -#endif } } diff --git a/src/Uno.UI/UI/Xaml/DependencyProperty.cs b/src/Uno.UI/UI/Xaml/DependencyProperty.cs index 9f7b791c585e..439c6a03b357 100644 --- a/src/Uno.UI/UI/Xaml/DependencyProperty.cs +++ b/src/Uno.UI/UI/Xaml/DependencyProperty.cs @@ -582,7 +582,11 @@ internal object GetDefaultValue(DependencyObject referenceObject, Type forType) } } - // TODO: Handle DependencyProperty.CreateDefaultValueCallback when implemented. + if (_ownerTypeMetadata.CreateDefaultValueCallback != null) + { + return _ownerTypeMetadata.CreateDefaultValueCallback(); + } + return _ownerTypeMetadata.DefaultValue; } diff --git a/src/Uno.UI/UI/Xaml/FrameworkPropertyMetadata.cs b/src/Uno.UI/UI/Xaml/FrameworkPropertyMetadata.cs index b9f55d43a413..634c542f0608 100644 --- a/src/Uno.UI/UI/Xaml/FrameworkPropertyMetadata.cs +++ b/src/Uno.UI/UI/Xaml/FrameworkPropertyMetadata.cs @@ -96,6 +96,18 @@ BackingFieldUpdateCallback backingFieldUpdateCallback Options = options.WithDefault(); } + internal FrameworkPropertyMetadata( + object defaultValue, + FrameworkPropertyMetadataOptions options, + PropertyChangedCallback propertyChangedCallback, + CoerceValueCallback coerceValueCallback, + BackingFieldUpdateCallback backingFieldUpdateCallback, + CreateDefaultValueCallback createDefaultValueCallback + ) : base(defaultValue, propertyChangedCallback, coerceValueCallback, backingFieldUpdateCallback, createDefaultValueCallback) + { + Options = options.WithDefault(); + } + internal FrameworkPropertyMetadata( object defaultValue, PropertyChangedCallback propertyChangedCallback @@ -177,8 +189,7 @@ public bool HasWeakStorage internal override PropertyMetadata CloneWithOverwrittenDefaultValue(object newDefaultValue) { - // This should clone CreateDefaultValueCallback when it's supported - return new FrameworkPropertyMetadata(newDefaultValue, Options, PropertyChangedCallback, CoerceValueCallback, BackingFieldUpdateCallback); + return new FrameworkPropertyMetadata(newDefaultValue, Options, PropertyChangedCallback, CoerceValueCallback, BackingFieldUpdateCallback, CreateDefaultValueCallback); } } } diff --git a/src/Uno.UI/UI/Xaml/PropertyMetadata.cs b/src/Uno.UI/UI/Xaml/PropertyMetadata.cs index d5df41fd7308..3e986abf13e9 100644 --- a/src/Uno.UI/UI/Xaml/PropertyMetadata.cs +++ b/src/Uno.UI/UI/Xaml/PropertyMetadata.cs @@ -119,6 +119,34 @@ BackingFieldUpdateCallback backingFieldUpdateCallback BackingFieldUpdateCallback = backingFieldUpdateCallback; } + internal PropertyMetadata( + object defaultValue, + PropertyChangedCallback propertyChangedCallback, + CoerceValueCallback coerceValueCallback, + BackingFieldUpdateCallback backingFieldUpdateCallback, + CreateDefaultValueCallback createDefaultValueCallback + ) + { + DefaultValue = defaultValue; + PropertyChangedCallback = propertyChangedCallback; + CoerceValueCallback = coerceValueCallback; + BackingFieldUpdateCallback = backingFieldUpdateCallback; + CreateDefaultValueCallback = createDefaultValueCallback; + } + + private PropertyMetadata(CreateDefaultValueCallback createDefaultValueCallback) + { + CreateDefaultValueCallback = createDefaultValueCallback; + } + + private PropertyMetadata(CreateDefaultValueCallback createDefaultValueCallback, PropertyChangedCallback propertyChangedCallback) + { + CreateDefaultValueCallback = createDefaultValueCallback; + PropertyChangedCallback = propertyChangedCallback; + } + + public CreateDefaultValueCallback CreateDefaultValueCallback { get; } + public object DefaultValue { get; } public PropertyChangedCallback PropertyChangedCallback { get; internal set; } @@ -127,6 +155,18 @@ BackingFieldUpdateCallback backingFieldUpdateCallback internal BackingFieldUpdateCallback BackingFieldUpdateCallback { get; set; } + public static PropertyMetadata Create(object defaultValue) + => new PropertyMetadata(defaultValue: defaultValue); + + public static PropertyMetadata Create(object defaultValue, PropertyChangedCallback propertyChangedCallback) + => new PropertyMetadata(defaultValue: defaultValue, propertyChangedCallback: propertyChangedCallback); + + public static PropertyMetadata Create(CreateDefaultValueCallback createDefaultValueCallback) + => new PropertyMetadata(createDefaultValueCallback: createDefaultValueCallback); + + public static PropertyMetadata Create(CreateDefaultValueCallback createDefaultValueCallback, PropertyChangedCallback propertyChangedCallback) + => new PropertyMetadata(createDefaultValueCallback: createDefaultValueCallback, propertyChangedCallback: propertyChangedCallback); + internal void MergePropertyChangedCallback(PropertyChangedCallback callback) { PropertyChangedCallback += callback; @@ -146,8 +186,7 @@ internal void RaiseBackingFieldUpdate(DependencyObject source, object newValue) internal virtual PropertyMetadata CloneWithOverwrittenDefaultValue(object newDefaultValue) { - // This should clone CreateDefaultValueCallback when it's supported - return new PropertyMetadata(newDefaultValue, PropertyChangedCallback, CoerceValueCallback, BackingFieldUpdateCallback); + return new PropertyMetadata(newDefaultValue, PropertyChangedCallback, CoerceValueCallback, BackingFieldUpdateCallback, CreateDefaultValueCallback); } } }