summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Xamarin.Forms.Core.UnitTests/BindableObjectUnitTests.cs84
-rw-r--r--Xamarin.Forms.Core/BindableObject.cs7
2 files changed, 88 insertions, 3 deletions
diff --git a/Xamarin.Forms.Core.UnitTests/BindableObjectUnitTests.cs b/Xamarin.Forms.Core.UnitTests/BindableObjectUnitTests.cs
index 7c4bac7a..c46f7c0e 100644
--- a/Xamarin.Forms.Core.UnitTests/BindableObjectUnitTests.cs
+++ b/Xamarin.Forms.Core.UnitTests/BindableObjectUnitTests.cs
@@ -111,6 +111,90 @@ namespace Xamarin.Forms.Core.UnitTests
}
[Test]
+ public void BindingContextChangedOnce()
+ {
+ var count = 0;
+
+ var mock = new MockBindable();
+ mock.BindingContextChanged += (sender, args) => ++count;
+
+ mock.BindingContext = new object();
+ Assert.AreEqual(count, 1);
+ }
+
+ [Test]
+ public void ParentAndChildBindingContextChanged()
+ {
+ int parentCount = 0, childCount = 0;
+
+ var didNotChange = " BindingContext did not change.";
+ var changedMoreThanOnce = " BindingContext changed more than once.";
+ var changedWhenNoChange = " BindingContext was changed when there was no change in context.";
+
+ var parent = new MockBindable();
+ parent.BindingContextChanged += (sender, args) => { ++parentCount; };
+
+ var child = new MockBindable();
+ child.BindingContextChanged += (sender, args) => { ++childCount; };
+
+ child.Parent = parent;
+ Assert.AreEqual(parentCount, 0, "Parent BindingContext was changed while parenting a child.");
+ Assert.AreEqual(childCount, 0, "Child" + changedWhenNoChange);
+
+ child.BindingContext = new object(); // set manually
+ Assert.GreaterOrEqual(childCount, 1, "Child" + didNotChange);
+ Assert.AreEqual(childCount, 1, "Child" + changedMoreThanOnce);
+ Assert.AreEqual(parentCount, 0, "Parent" + changedWhenNoChange);
+
+ parent.BindingContext = new object();
+ Assert.GreaterOrEqual(parentCount, 1, "Parent" + didNotChange);
+ Assert.AreEqual(parentCount, 1, "Parent" + changedMoreThanOnce);
+ Assert.AreEqual(childCount, 1, "Child" + changedWhenNoChange);
+
+ child.BindingContext = new object();
+ Assert.GreaterOrEqual(childCount, 2, "Child" + didNotChange);
+ Assert.AreEqual(childCount, 2, "Child" + changedMoreThanOnce);
+ Assert.AreEqual(parentCount, 1, "Parent" + changedWhenNoChange);
+ }
+
+ [Test]
+ public void ParentSetOnNullChildBindingContext()
+ {
+ var parent = new MockBindable();
+
+ var child = new MockBindable();
+ child.BindingContextChanged += (sender, args) => { Assert.Fail("Child BindingContext was changed when there was no change in context."); };
+
+ child.Parent = parent; // this should not trigger binding context change on child since there is no change
+ parent.BindingContext = new object();
+ parent.BindingContext = new object();
+ }
+
+ [Test]
+ public void ParentSetOnNonNullChildBindingContext()
+ {
+ var count = 0;
+
+ var parent = new MockBindable();
+ parent.BindingContextChanged += (sender, args) => { ++count; };
+
+ var child = new MockBindable();
+ child.BindingContextChanged += (sender, args) => { ++count; };
+
+ child.BindingContext = new object(); // set manually
+ Assert.AreEqual(count, 1);
+
+ child.Parent = parent; // this should not trigger binding context change because child binding was set manually
+ Assert.AreEqual(count, 1);
+
+ parent.BindingContext = new object();
+ Assert.AreEqual(count, 2);
+
+ child.BindingContext = new object();
+ Assert.AreEqual(count, 3);
+ }
+
+ [Test]
[Description ("When the BindingContext changes, any bindings should be immediately applied.")]
public void BindingContextChangedBindingsApplied()
{
diff --git a/Xamarin.Forms.Core/BindableObject.cs b/Xamarin.Forms.Core/BindableObject.cs
index fdf2afad..217f4a94 100644
--- a/Xamarin.Forms.Core/BindableObject.cs
+++ b/Xamarin.Forms.Core/BindableObject.cs
@@ -98,6 +98,10 @@ namespace Xamarin.Forms
return;
object oldContext = bindable._inheritedContext;
+
+ if (ReferenceEquals(oldContext, value))
+ return;
+
if (bpContext != null && oldContext == null)
oldContext = bpContext.Value;
@@ -108,9 +112,6 @@ namespace Xamarin.Forms
}
else
{
- if (ReferenceEquals(oldContext, value))
- return;
-
bindable._inheritedContext = value;
}