From 127133eb89d2a14380a26475bad9f9c049836203 Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Wed, 17 Feb 2016 18:59:27 +0100 Subject: [PATCH] Added enum conversions to DefaultValueConverter. --- .../Perspex.Markup/DefaultValueConverter.cs | 35 ++++++++++++++- src/Perspex.Base/Utilities/TypeUtilities.cs | 10 +++-- .../DefaultValueConverterTests.cs | 43 +++++++++++++++++-- 3 files changed, 81 insertions(+), 7 deletions(-) diff --git a/src/Markup/Perspex.Markup/DefaultValueConverter.cs b/src/Markup/Perspex.Markup/DefaultValueConverter.cs index e49c1c3ae6..23bb0f774c 100644 --- a/src/Markup/Perspex.Markup/DefaultValueConverter.cs +++ b/src/Markup/Perspex.Markup/DefaultValueConverter.cs @@ -3,6 +3,8 @@ using System; using System.Globalization; +using System.Linq; +using System.Reflection; using Perspex.Utilities; namespace Perspex.Markup @@ -30,7 +32,9 @@ namespace Perspex.Markup { object result; - if (value != null && TypeUtilities.TryConvert(targetType, value, culture, out result)) + if (value != null && + (TypeUtilities.TryConvert(targetType, value, culture, out result) || + TryConvertEnum(value, targetType, culture, out result))) { return result; } @@ -52,5 +56,34 @@ namespace Perspex.Markup { return Convert(value, targetType, parameter, culture); } + + private bool TryConvertEnum(object value, Type targetType, CultureInfo cultur, out object result) + { + var valueTypeInfo = value.GetType().GetTypeInfo(); + var targetTypeInfo = targetType.GetTypeInfo(); + + if (valueTypeInfo.IsEnum && !targetTypeInfo.IsEnum) + { + var enumValue = (int)value; + + if (TypeUtilities.TryCast(targetType, enumValue, out result)) + { + return true; + } + } + else if (!valueTypeInfo.IsEnum && targetTypeInfo.IsEnum) + { + object intValue; + + if (TypeUtilities.TryCast(typeof(int), value, out intValue)) + { + result = Enum.ToObject(targetType, intValue); + return true; + } + } + + result = null; + return false; + } } } diff --git a/src/Perspex.Base/Utilities/TypeUtilities.cs b/src/Perspex.Base/Utilities/TypeUtilities.cs index 3d19de5f97..c6d16d56b2 100644 --- a/src/Perspex.Base/Utilities/TypeUtilities.cs +++ b/src/Perspex.Base/Utilities/TypeUtilities.cs @@ -119,6 +119,12 @@ namespace Perspex.Utilities return true; } + if (to == typeof(string)) + { + result = Convert.ToString(value); + return true; + } + if (to.GetTypeInfo().IsEnum && from == typeof(string)) { if (Enum.IsDefined(to, (string)value)) @@ -131,9 +137,7 @@ namespace Perspex.Utilities bool containsFrom = Conversions.ContainsKey(from); bool containsTo = Conversions.ContainsKey(to); - if ((containsFrom && containsTo) || - (from == typeof(string) && containsTo) || - (to == typeof(string) && containsFrom)) + if ((containsFrom && containsTo) || (from == typeof(string) && containsTo)) { try { diff --git a/tests/Perspex.Markup.UnitTests/DefaultValueConverterTests.cs b/tests/Perspex.Markup.UnitTests/DefaultValueConverterTests.cs index b438d6af1d..55034a3c53 100644 --- a/tests/Perspex.Markup.UnitTests/DefaultValueConverterTests.cs +++ b/tests/Perspex.Markup.UnitTests/DefaultValueConverterTests.cs @@ -2,6 +2,7 @@ // Licensed under the MIT license. See licence.md file in the project root for full license information. using System.Globalization; +using Perspex.Controls; using Xunit; namespace Perspex.Markup.UnitTests @@ -44,6 +45,18 @@ namespace Perspex.Markup.UnitTests Assert.Equal(TestEnum.Bar, result); } + [Fact] + public void Can_Convert_Int_To_Enum() + { + var result = DefaultValueConverter.Instance.Convert( + 1, + typeof(TestEnum), + null, + CultureInfo.InvariantCulture); + + Assert.Equal(TestEnum.Bar, result); + } + [Fact] public void Can_Convert_Double_To_String() { @@ -57,15 +70,27 @@ namespace Perspex.Markup.UnitTests } [Fact] - public void Can_Convert_Double_To_Int() + public void Can_Convert_Enum_To_Int() { var result = DefaultValueConverter.Instance.Convert( - 5.0, + TestEnum.Bar, typeof(int), null, CultureInfo.InvariantCulture); - Assert.Equal(5, result); + Assert.Equal(1, result); + } + + [Fact] + public void Can_Convert_Enum_To_String() + { + var result = DefaultValueConverter.Instance.Convert( + TestEnum.Bar, + typeof(string), + null, + CultureInfo.InvariantCulture); + + Assert.Equal("Bar", result); } [Fact] @@ -80,6 +105,18 @@ namespace Perspex.Markup.UnitTests Assert.Equal(5.0, result); } + [Fact] + public void Cannot_Convert_Between_Different_Enum_Types() + { + var result = DefaultValueConverter.Instance.Convert( + TestEnum.Foo, + typeof(Orientation), + null, + CultureInfo.InvariantCulture); + + Assert.Equal(PerspexProperty.UnsetValue, result); + } + private enum TestEnum { Foo,