BindingContext changes are called multiple times on app start (#470)

* inherited binding context fix

* add check for child binding context

* Revert "add check for child binding context"

This reverts commit 71952f39129cfedc2358a32100deb07bd32a3080.

* unit tests
This commit is contained in:
adrianknight89 2016-11-16 02:24:21 -06:00 коммит произвёл Stephane Delcroix
Родитель 46104e9ce1
Коммит 107ed5e545
2 изменённых файлов: 88 добавлений и 3 удалений

Просмотреть файл

@ -110,6 +110,90 @@ namespace Xamarin.Forms.Core.UnitTests
Assert.Fail ("The BindingContextChanged event was not fired.");
}
[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()

Просмотреть файл

@ -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;
}