public void StringFormatOneWayToSource() { var property = BindableProperty.Create("Foo", typeof(string), typeof(MockBindable)); var binding = CreateBinding(BindingMode.OneWayToSource, "Foo {0}"); var vm = new MockViewModel { Text = "Bar" }; var bo = new MockBindable { BindingContext = vm }; bo.SetBinding(property, binding); bo.SetValue(property, "Bar"); Assert.That(vm.Text, Is.EqualTo("Bar")); }
public void StringFormatOnUpdate() { var property = BindableProperty.Create("Foo", typeof(string), typeof(MockBindable)); var binding = CreateBinding(BindingMode.Default, "Foo {0}"); var vm = new MockViewModel { Text = "Bar" }; var bo = new MockBindable { BindingContext = vm }; bo.SetBinding(property, binding); vm.Text = "Baz"; Assert.That(bo.GetValue(property), Is.EqualTo("Foo Baz")); }
public void SourceAndTargetAreWeakWeakSimplePath(BindingMode mode) { var property = BindableProperty.Create("Text", typeof(string), typeof(MockBindable), "default value", BindingMode.OneWay); var binding = CreateBinding(mode); WeakReference weakViewModel = null, weakBindable = null; int i = 0; Action create = null; create = () => { if (i++ < 1024) { create(); return; } MockBindable bindable = new MockBindable(); weakBindable = new WeakReference(bindable); MockViewModel viewmodel = new MockViewModel(); weakViewModel = new WeakReference(viewmodel); bindable.BindingContext = viewmodel; bindable.SetBinding(property, binding); Assume.That(() => bindable.BindingContext = null, Throws.Nothing); }; create(); GC.Collect(); GC.WaitForPendingFinalizers(); if (mode == BindingMode.TwoWay || mode == BindingMode.OneWay) { Assert.IsFalse(weakViewModel.IsAlive, "ViewModel wasn't collected"); } if (mode == BindingMode.TwoWay || mode == BindingMode.OneWayToSource) { Assert.IsFalse(weakBindable.IsAlive, "Bindable wasn't collected"); } }
public void ValueUpdatedWithSimplePathOnTwoWayBinding( [Values(true, false)] bool isDefault) { const string newvalue = "New Value"; var viewmodel = new MockViewModel { Text = "Foo" }; BindingMode propertyDefault = BindingMode.OneWay; BindingMode bindingMode = BindingMode.TwoWay; if (isDefault) { propertyDefault = BindingMode.TwoWay; bindingMode = BindingMode.Default; } var property = BindableProperty.Create("Text", typeof(string), typeof(MockBindable), "default value", propertyDefault); var binding = CreateBinding(bindingMode); var bindable = new MockBindable(); bindable.BindingContext = viewmodel; bindable.SetBinding(property, binding); viewmodel.Text = newvalue; Assert.AreEqual(newvalue, bindable.GetValue(property), "Target property did not update change"); Assert.AreEqual(newvalue, viewmodel.Text, "Source property changed from what it was set to"); const string newvalue2 = "New Value in the other direction"; bindable.SetValue(property, newvalue2); Assert.AreEqual(newvalue2, viewmodel.Text, "Source property did not update with Target's change"); Assert.AreEqual(newvalue2, bindable.GetValue(property), "Target property changed from what it was set to"); Assert.That(log.Messages.Count, Is.EqualTo(0), "An error was logged: " + log.Messages.FirstOrDefault()); }
public void ValueUpdatedWithSimplePathOnOneWayToSourceBinding( [Values(true, false)] bool isDefault) { const string newvalue = "New Value"; var viewmodel = new MockViewModel { Text = "Foo" }; BindingMode propertyDefault = BindingMode.OneWay; BindingMode bindingMode = BindingMode.OneWayToSource; if (isDefault) { propertyDefault = BindingMode.OneWayToSource; bindingMode = BindingMode.Default; } var property = BindableProperty.Create("Text", typeof(string), typeof(MockBindable), "default value", propertyDefault); var binding = CreateBinding(bindingMode); var bindable = new MockBindable(); bindable.BindingContext = viewmodel; bindable.SetBinding(property, binding); string original = (string)bindable.GetValue(property); const string value = "value"; viewmodel.Text = value; Assert.AreEqual(original, bindable.GetValue(property), "Target updated from Source on OneWayToSource"); bindable.SetValue(property, newvalue); Assert.AreEqual(newvalue, bindable.GetValue(property), "Bindable did not update on binding context property change"); Assert.AreEqual(newvalue, viewmodel.Text, "Source property changed when it shouldn't"); Assert.That(log.Messages.Count, Is.EqualTo(0), "An error was logged: " + log.Messages.FirstOrDefault()); }
public void ValueSetOnTwoWay( [Values(true, false)] bool setContextFirst, [Values(true, false)] bool isDefault) { const string value = "Foo"; var viewmodel = new MockViewModel { Text = value }; BindingMode propertyDefault = BindingMode.OneWay; BindingMode bindingMode = BindingMode.TwoWay; if (isDefault) { propertyDefault = BindingMode.TwoWay; bindingMode = BindingMode.Default; } var property = BindableProperty.Create("Text", typeof(string), typeof(MockBindable), defaultValue: "default value", defaultBindingMode: propertyDefault); var binding = CreateBinding(bindingMode); var bindable = new MockBindable(); if (setContextFirst) { bindable.BindingContext = viewmodel; bindable.SetBinding(property, binding); } else { bindable.SetBinding(property, binding); bindable.BindingContext = viewmodel; } Assert.AreEqual(value, viewmodel.Text, "BindingContext property changed"); Assert.AreEqual(value, bindable.GetValue(property), "Target property did not change"); Assert.That(log.Messages.Count, Is.EqualTo(0), "An error was logged: " + log.Messages.FirstOrDefault()); }
public void PropertyChangeBindingsOccurThroughMainThread() { var vm = new MockViewModel { Text = "text" }; var bindable = new MockBindable(); var binding = CreateBinding(); bindable.BindingContext = vm; bindable.SetBinding(MockBindable.TextProperty, binding); bool invokeOnMainThreadWasCalled = false; Device.PlatformServices = new MockPlatformServices(a => invokeOnMainThreadWasCalled = true, isInvokeRequired: true); vm.Text = "updated"; // If we wait five seconds and invokeOnMainThreadWasCalled still hasn't been set, something is very wrong Assert.That(invokeOnMainThreadWasCalled, Is.True.After(5000, 10)); }
public void ReuseBindingInstance() { var vm = new MockViewModel(); var bindable = new MockBindable(); bindable.BindingContext = vm; var property = BindableProperty.Create("Foo", typeof(string), typeof(MockBindable)); var binding = new Binding("Text"); bindable.SetBinding(property, binding); var bindable2 = new MockBindable(); bindable2.BindingContext = new MockViewModel(); Assert.Throws <InvalidOperationException>(() => bindable2.SetBinding(property, binding), "Binding allowed reapplication with a different context"); GC.KeepAlive(bindable); }
public void ValueUpdatedWithOldContextDoesNotUpdateWithTwoWayBinding(bool isDefault) { const string newvalue = "New Value"; var viewmodel = new MockViewModel { Text = "Foo" }; BindingMode propertyDefault = BindingMode.OneWay; BindingMode bindingMode = BindingMode.TwoWay; if (isDefault) { propertyDefault = BindingMode.TwoWay; bindingMode = BindingMode.Default; } var property = BindableProperty.Create("Text", typeof(string), typeof(MockBindable), "default value", propertyDefault); var binding = CreateBinding(bindingMode); var bindable = new MockBindable(); bindable.BindingContext = viewmodel; bindable.SetBinding(property, binding); bindable.BindingContext = new MockViewModel(); Assert.AreEqual(null, bindable.GetValue(property)); viewmodel.Text = newvalue; Assert.AreEqual(null, bindable.GetValue(property), "Target updated from old Source property change"); string original = viewmodel.Text; bindable.SetValue(property, newvalue); Assert.AreEqual(original, viewmodel.Text, "Source updated from old Target property change"); Assert.That(log.Messages.Count, Is.EqualTo(0), "An error was logged: " + log.Messages.FirstOrDefault()); }