Skip to content

Commit

Permalink
Support default value for value types in BindableProperty (xamarin#2827)
Browse files Browse the repository at this point in the history
* Support default value for value types in BindableProperty when no explicit default is provided

* Add unit test for enum/struct BindableProperty default values
  • Loading branch information
activa authored and StephaneDelcroix committed May 29, 2018
1 parent 7cab837 commit 6d74745
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 1 deletion.
61 changes: 61 additions & 0 deletions Xamarin.Forms.Core.UnitTests/BindablePropertyUnitTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -131,5 +131,66 @@ public void NullableProperty ()
bindable.SetValue (prop, null);
Assert.AreEqual (null, bindable.GetValue (prop));
}

[Test]
public void ValueTypePropertyDefaultValue ()
{
// Create BindableProperty without explicit default value
var prop = BindableProperty.Create ("foo", typeof(int), typeof(MockBindable));
Assert.AreEqual (typeof(int), prop.ReturnType);

Assert.AreEqual(prop.DefaultValue, 0);

var bindable = new MockBindable ();
Assert.AreEqual (0, bindable.GetValue (prop));

bindable.SetValue (prop, 1);
Assert.AreEqual (1, bindable.GetValue (prop));
}

enum TestEnum
{
One,Two,Three
}

[Test]
public void EnumPropertyDefaultValue ()
{
// Create BindableProperty without explicit default value
var prop = BindableProperty.Create ("foo", typeof(TestEnum), typeof(MockBindable));
Assert.AreEqual (typeof(TestEnum), prop.ReturnType);

Assert.AreEqual(prop.DefaultValue, default(TestEnum));

var bindable = new MockBindable ();
Assert.AreEqual (default(TestEnum), bindable.GetValue (prop));

bindable.SetValue (prop, TestEnum.Two);
Assert.AreEqual (TestEnum.Two, bindable.GetValue (prop));
}

struct TestStruct
{
public int IntValue;
}

[Test]
public void StructPropertyDefaultValue ()
{
// Create BindableProperty without explicit default value
var prop = BindableProperty.Create ("foo", typeof(TestStruct), typeof(MockBindable));
Assert.AreEqual (typeof(TestStruct), prop.ReturnType);

Assert.AreEqual(((TestStruct)prop.DefaultValue).IntValue, default(int));

var bindable = new MockBindable ();
Assert.AreEqual (default(int), ((TestStruct)bindable.GetValue (prop)).IntValue);

var propStruct = new TestStruct {IntValue = 1};

bindable.SetValue (prop, propStruct);
Assert.AreEqual (1, ((TestStruct)bindable.GetValue (prop)).IntValue);
}

}
}
5 changes: 4 additions & 1 deletion Xamarin.Forms.Core/BindableProperty.cs
Original file line number Diff line number Diff line change
Expand Up @@ -68,10 +68,13 @@ public sealed class BindableProperty
// don't use Enum.IsDefined as its redonkulously expensive for what it does
if (defaultBindingMode != BindingMode.Default && defaultBindingMode != BindingMode.OneWay && defaultBindingMode != BindingMode.OneWayToSource && defaultBindingMode != BindingMode.TwoWay && defaultBindingMode != BindingMode.OneTime)
throw new ArgumentException("Not a valid type of BindingMode", "defaultBindingMode");

if (defaultValue == null && Nullable.GetUnderlyingType(returnType) == null && returnType.GetTypeInfo().IsValueType)
throw new ArgumentException("Not a valid default value", "defaultValue");
defaultValue = Activator.CreateInstance(returnType);

if (defaultValue != null && !returnType.IsInstanceOfType(defaultValue))
throw new ArgumentException("Default value did not match return type", "defaultValue");

if (defaultBindingMode == BindingMode.Default)
defaultBindingMode = BindingMode.OneWay;

Expand Down

0 comments on commit 6d74745

Please sign in to comment.