Browse Source

Add more conversions to DefaultValueConverter.

pull/301/head
Steven Kirk 11 years ago
parent
commit
321bc8c001
  1. 47
      src/Perspex.Base/Utilities/TypeUtilities.cs
  2. 57
      tests/Perspex.Markup.UnitTests/DefaultValueConverterTests.cs

47
src/Perspex.Base/Utilities/TypeUtilities.cs

@ -74,9 +74,8 @@ namespace Perspex.Utilities
}
else
{
var cast = from.GetTypeInfo()
.GetDeclaredMethods("op_Implicit")
.FirstOrDefault(m => m.ReturnType == to);
var cast = from.GetRuntimeMethods()
.FirstOrDefault(m => m.Name == "op_Implicit" && m.ReturnType == to);
if (cast != null)
{
@ -100,9 +99,27 @@ namespace Perspex.Utilities
/// <returns>True if the cast was sucessful, otherwise false.</returns>
public static bool TryConvert(Type to, object value, CultureInfo culture, out object result)
{
var valueType = value.GetType();
if (value == null)
{
result = null;
return AcceptsNull(to);
}
var from = value.GetType();
if (value == PerspexProperty.UnsetValue)
{
result = value;
return true;
}
if (to.GetTypeInfo().IsEnum && valueType == typeof(string))
if (to.GetTypeInfo().IsAssignableFrom(from.GetTypeInfo()))
{
result = value;
return true;
}
if (to.GetTypeInfo().IsEnum && from == typeof(string))
{
if (Enum.IsDefined(to, (string)value))
{
@ -111,8 +128,12 @@ namespace Perspex.Utilities
}
}
if ((valueType == typeof(string) && Conversions.ContainsKey(to)) ||
(to == typeof(string) && Conversions.ContainsKey(value.GetType())))
bool containsFrom = Conversions.ContainsKey(from);
bool containsTo = Conversions.ContainsKey(to);
if ((containsFrom && containsTo) ||
(from == typeof(string) && containsTo) ||
(to == typeof(string) && containsFrom))
{
try
{
@ -125,10 +146,18 @@ namespace Perspex.Utilities
return false;
}
}
else
var cast = from.GetRuntimeMethods()
.FirstOrDefault(m => (m.Name == "op_Implicit" || m.Name == "op_Explicit") && m.ReturnType == to);
if (cast != null)
{
return TryCast(to, value, out result);
result = cast.Invoke(null, new[] { value });
return true;
}
result = null;
return false;
}
/// <summary>

57
tests/Perspex.Markup.UnitTests/DefaultValueConverterTests.cs

@ -32,6 +32,18 @@ namespace Perspex.Markup.UnitTests
Assert.Equal(5.0, result);
}
[Fact]
public void Can_Convert_String_To_Enum()
{
var result = DefaultValueConverter.Instance.Convert(
"Bar",
typeof(TestEnum),
null,
CultureInfo.InvariantCulture);
Assert.Equal(TestEnum.Bar, result);
}
[Fact]
public void Can_Convert_Double_To_String()
{
@ -43,5 +55,50 @@ namespace Perspex.Markup.UnitTests
Assert.Equal("5", result);
}
[Fact]
public void Can_Convert_Double_To_Int()
{
var result = DefaultValueConverter.Instance.Convert(
5.0,
typeof(int),
null,
CultureInfo.InvariantCulture);
Assert.Equal(5, result);
}
[Fact]
public void Can_Use_Explicit_Cast()
{
var result = DefaultValueConverter.Instance.Convert(
new ExplicitDouble(5.0),
typeof(double),
null,
CultureInfo.InvariantCulture);
Assert.Equal(5.0, result);
}
private enum TestEnum
{
Foo,
Bar,
}
private class ExplicitDouble
{
public ExplicitDouble(double value)
{
Value = value;
}
public double Value { get; }
public static explicit operator double (ExplicitDouble v)
{
return v.Value;
}
}
}
}

Loading…
Cancel
Save