diff --git a/src/SourceGenerators/Uno.UI.SourceGenerators/BindableTypeProviders/BindableTypeProvidersGenerationTask.cs b/src/SourceGenerators/Uno.UI.SourceGenerators/BindableTypeProviders/BindableTypeProvidersGenerationTask.cs index bbaf6f7fa1ae..3486da5c93dc 100644 --- a/src/SourceGenerators/Uno.UI.SourceGenerators/BindableTypeProviders/BindableTypeProvidersGenerationTask.cs +++ b/src/SourceGenerators/Uno.UI.SourceGenerators/BindableTypeProviders/BindableTypeProvidersGenerationTask.cs @@ -376,12 +376,11 @@ where field.IsStatic && property.SetMethod.IsLocallyPublic(_currentModule!) ) { - if (property.Type.IsValueType) - { - writer.AppendLineIndented($@"bindableType.AddProperty(""{propertyName}"", typeof({propertyTypeName}), Get{propertyName}, Set{propertyName});"); - - postWriter.AppendLineIndented($@"private static object Get{propertyName}(object instance, Microsoft.UI.Xaml.DependencyPropertyValuePrecedences? precedence) => (({ownerTypeName})instance).{propertyName};"); + writer.AppendLineIndented($@"bindableType.AddProperty(""{propertyName}"", typeof({propertyTypeName}), Get{propertyName}, Set{propertyName});"); + postWriter.AppendLineIndented($@"private static object Get{propertyName}(object instance, Microsoft.UI.Xaml.DependencyPropertyValuePrecedences? precedence) => (({ownerTypeName})instance).{propertyName};"); + if (property.Type.IsValueType && property.Type.OriginalDefinition.SpecialType != SpecialType.System_Nullable_T) + { using (postWriter.BlockInvariant($@"private static void Set{propertyName}(object instance, object value, Microsoft.UI.Xaml.DependencyPropertyValuePrecedences? precedence)")) { using (postWriter.BlockInvariant($"if(value != null)")) @@ -392,9 +391,6 @@ where field.IsStatic } else { - writer.AppendLineIndented($@"bindableType.AddProperty(""{propertyName}"", typeof({propertyTypeName}), Get{propertyName}, Set{propertyName});"); - - postWriter.AppendLineIndented($@"private static object Get{propertyName}(object instance, Microsoft.UI.Xaml.DependencyPropertyValuePrecedences? precedence) => (({ownerTypeName})instance).{propertyName};"); postWriter.AppendLineIndented($@"private static void Set{propertyName}(object instance, object value, Microsoft.UI.Xaml.DependencyPropertyValuePrecedences? precedence) => (({ownerTypeName})instance).{propertyName} = ({propertyTypeName})value;"); } diff --git a/src/Uno.UI.RuntimeTests/Tests/Windows_UI_Xaml_Data/BindableNullableValueTypeTestPage.xaml b/src/Uno.UI.RuntimeTests/Tests/Windows_UI_Xaml_Data/BindableNullableValueTypeTestPage.xaml new file mode 100644 index 000000000000..9db73695b53b --- /dev/null +++ b/src/Uno.UI.RuntimeTests/Tests/Windows_UI_Xaml_Data/BindableNullableValueTypeTestPage.xaml @@ -0,0 +1,14 @@ + + + + + + diff --git a/src/Uno.UI.RuntimeTests/Tests/Windows_UI_Xaml_Data/BindableNullableValueTypeTestPage.xaml.cs b/src/Uno.UI.RuntimeTests/Tests/Windows_UI_Xaml_Data/BindableNullableValueTypeTestPage.xaml.cs new file mode 100644 index 000000000000..60bc58fdc2bb --- /dev/null +++ b/src/Uno.UI.RuntimeTests/Tests/Windows_UI_Xaml_Data/BindableNullableValueTypeTestPage.xaml.cs @@ -0,0 +1,33 @@ +#nullable enable + +using System.ComponentModel; +using Microsoft.UI.Xaml.Controls; + +namespace Uno.UI.RuntimeTests.Tests.Windows_UI_Xaml_Data; + +[Bindable(true)] +public sealed partial class BindableNullableValueTypeTestPage : Page, INotifyPropertyChanged +{ + private int? _myProperty; + + public BindableNullableValueTypeTestPage() + { + this.InitializeComponent(); + this.DataContext = this; + } + + public event PropertyChangedEventHandler? PropertyChanged; + + public int? MyProperty + { + get => _myProperty; + set + { + if (_myProperty != value) + { + _myProperty = value; + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(MyProperty))); + } + } + } +} diff --git a/src/Uno.UI.RuntimeTests/Tests/Windows_UI_Xaml_Data/Given_BindableNullableValueType.cs b/src/Uno.UI.RuntimeTests/Tests/Windows_UI_Xaml_Data/Given_BindableNullableValueType.cs new file mode 100644 index 000000000000..a024b2222c0d --- /dev/null +++ b/src/Uno.UI.RuntimeTests/Tests/Windows_UI_Xaml_Data/Given_BindableNullableValueType.cs @@ -0,0 +1,23 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Text; + +namespace Uno.UI.RuntimeTests.Tests.Windows_UI_Xaml_Data; + +[TestClass] +public class Given_BindableNullableValueType +{ + [TestMethod] + [RunsOnUIThread] + public void When_BindableNullableValueTypeTestPage() + { + var x = new BindableNullableValueTypeTestPage(); + var tb = x.textBlock; + tb.Tag = "10"; + Assert.AreEqual(10, x.MyProperty); + tb.Tag = null; + Assert.AreEqual(null, x.MyProperty); + } +}