diff --git a/src/Perspex.Base/PerspexObject.cs b/src/Perspex.Base/PerspexObject.cs
index 03d5fecd69..696d01893a 100644
--- a/src/Perspex.Base/PerspexObject.cs
+++ b/src/Perspex.Base/PerspexObject.cs
@@ -605,7 +605,9 @@ namespace Perspex
property,
GetDescription(source));
- return source.Subscribe(x => SetValue(property, x));
+ return source
+ .Select(x => TypeUtilities.CastOrDefault(x, property.PropertyType, false))
+ .Subscribe(x => SetValue(property, x));
}
else
{
diff --git a/src/Perspex.Base/Utilities/TypeUtilities.cs b/src/Perspex.Base/Utilities/TypeUtilities.cs
index 98909d9801..d026efc622 100644
--- a/src/Perspex.Base/Utilities/TypeUtilities.cs
+++ b/src/Perspex.Base/Utilities/TypeUtilities.cs
@@ -32,8 +32,9 @@ namespace Perspex.Utilities
/// The type to cast to.
/// The value to cast.
/// If sucessful, contains the cast value.
+ /// Allow .
/// True if the cast was sucessful, otherwise false.
- public static bool TryCast(Type to, object value, out object result)
+ public static bool TryCast(Type to, object value, out object result, bool allowUnset = true)
{
Contract.Requires(to != null);
@@ -46,7 +47,7 @@ namespace Perspex.Utilities
var from = value.GetType();
- if (value == PerspexProperty.UnsetValue)
+ if (allowUnset && value == PerspexProperty.UnsetValue)
{
result = value;
return true;
@@ -77,5 +78,32 @@ namespace Perspex.Utilities
result = null;
return false;
}
+
+ ///
+ /// Casts a value to a type, returning the default for that type if the value could not be
+ /// cast.
+ ///
+ /// The value to cast.
+ /// The type to cast to..
+ /// Allow .
+ /// A value of .
+ public static object CastOrDefault(object value, Type type, bool allowUnset = true)
+ {
+ var typeInfo = type.GetTypeInfo();
+ object result;
+
+ if (TypeUtilities.TryCast(type, value, out result, allowUnset))
+ {
+ return result;
+ }
+ else if (typeInfo.IsValueType)
+ {
+ return Activator.CreateInstance(type);
+ }
+ else
+ {
+ return null;
+ }
+ }
}
}
diff --git a/tests/Perspex.Base.UnitTests/PerspexObjectTests_Direct.cs b/tests/Perspex.Base.UnitTests/PerspexObjectTests_Direct.cs
index c8b4470d13..a9a2d5c1fc 100644
--- a/tests/Perspex.Base.UnitTests/PerspexObjectTests_Direct.cs
+++ b/tests/Perspex.Base.UnitTests/PerspexObjectTests_Direct.cs
@@ -148,6 +148,45 @@ namespace Perspex.Base.UnitTests
Assert.Equal("second", target.Foo);
}
+ [Fact]
+ public void Bind_Handles_Wrong_Type()
+ {
+ var target = new Class1();
+ var source = new Subject