From 6ea751f8930c3bd2e113834374b655b41ce8bb84 Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Thu, 2 Nov 2023 23:37:54 +0100 Subject: [PATCH] Make enum/int conversion work. --- .../Data/Core/TargetTypeConverter.cs | 6 +++ .../Core/BindingExpressionTests_Property.cs | 42 +++++++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/src/Avalonia.Base/Data/Core/TargetTypeConverter.cs b/src/Avalonia.Base/Data/Core/TargetTypeConverter.cs index 66f86baa99..8682126143 100644 --- a/src/Avalonia.Base/Data/Core/TargetTypeConverter.cs +++ b/src/Avalonia.Base/Data/Core/TargetTypeConverter.cs @@ -53,6 +53,12 @@ internal abstract class TargetTypeConverter return true; } + if (t.IsEnum && t.GetEnumUnderlyingType() == value.GetType()) + { + result = Enum.ToObject(t, value); + return true; + } + if (value is IConvertible convertible) { try diff --git a/tests/Avalonia.Base.UnitTests/Data/Core/BindingExpressionTests_Property.cs b/tests/Avalonia.Base.UnitTests/Data/Core/BindingExpressionTests_Property.cs index f416b0573e..45e7379a22 100644 --- a/tests/Avalonia.Base.UnitTests/Data/Core/BindingExpressionTests_Property.cs +++ b/tests/Avalonia.Base.UnitTests/Data/Core/BindingExpressionTests_Property.cs @@ -4,6 +4,7 @@ using System.Reactive; using System.Reactive.Linq; using System.Reactive.Subjects; using System.Threading.Tasks; +using Avalonia.Controls; using Avalonia.Data; using Avalonia.Data.Core; using Avalonia.Data.Core.ExpressionNodes.Reflection; @@ -345,6 +346,36 @@ namespace Avalonia.Base.UnitTests.Data.Core Assert.Equal(new[] { "NewName" }, result); } + [Theory] + [InlineData(true)] + [InlineData(false)] + public void Can_Convert_Int_To_Enum_Two_Way(bool allowReflection) + { + var data = new Class3 { IntValue = 1 }; + var control = new Control(); + var target = BindingExpression.Create( + data, + o => o.IntValue, + mode: BindingMode.TwoWay, + target: control, + targetProperty: DockPanel.DockProperty, + allowReflection: allowReflection); + var instance = new InstancedBinding( + target, + BindingMode.TwoWay, + BindingPriority.LocalValue); + + BindingOperations.Apply(control, DockPanel.DockProperty, instance); + + Assert.Equal(Dock.Bottom, DockPanel.GetDock(control)); + + DockPanel.SetDock(control, Dock.Right); + + Assert.Equal(2, data.IntValue); + + GC.KeepAlive(data); + } + public class MyViewModelBase { public object Name => "Name"; } public class MyViewModel : MyViewModelBase { public new string Name => "NewName"; } @@ -417,6 +448,17 @@ namespace Avalonia.Base.UnitTests.Data.Core private class Class3 : Class1 { + private int _intValue; + + public int IntValue + { + get => _intValue; + set + { + _intValue = value; + RaisePropertyChanged(nameof(IntValue)); + } + } } private class WithoutBar : NotifyingBase, INext