diff --git a/samples/BindingTest/MainWindow.paml b/samples/BindingTest/MainWindow.paml index 38e7c14d40..3ac2621738 100644 --- a/samples/BindingTest/MainWindow.paml +++ b/samples/BindingTest/MainWindow.paml @@ -1,9 +1,9 @@  - - - - + + + + \ No newline at end of file diff --git a/src/Markup/Perspex.Markup.Xaml/Binding/XamlBinding.cs b/src/Markup/Perspex.Markup.Xaml/Binding/XamlBinding.cs index 1bd2e86fd5..3e3e978f7c 100644 --- a/src/Markup/Perspex.Markup.Xaml/Binding/XamlBinding.cs +++ b/src/Markup/Perspex.Markup.Xaml/Binding/XamlBinding.cs @@ -5,6 +5,7 @@ using System; using System.Reactive.Linq; using System.Reactive.Subjects; using OmniXaml.TypeConversion; +using Perspex.Controls; using Perspex.Markup.Binding; namespace Perspex.Markup.Xaml.Binding @@ -26,8 +27,6 @@ namespace Perspex.Markup.Xaml.Binding public PerspexProperty TargetProperty { get; set; } - public object Source { get; set; } - public string SourcePropertyPath { get; set; } public BindingMode BindingMode { get; set; } @@ -39,20 +38,10 @@ namespace Perspex.Markup.Xaml.Binding public ExpressionObserver CreateExpressionObserver() { - var path = SourcePropertyPath; - var source = Source; - - if (source == null) - { - if (!string.IsNullOrWhiteSpace(path)) - { - path = "DataContext." + path; - } - - source = Target; - } - - return new ExpressionObserver(source, path); + var result = new ExpressionObserver(null, SourcePropertyPath); + var dataContext = Target.GetObservable(Control.DataContextProperty); + dataContext.Subscribe(x => result.Root = x); + return result; } internal void Bind(ISubject subject) @@ -70,7 +59,11 @@ namespace Perspex.Markup.Xaml.Binding Target.BindTwoWay(TargetProperty, subject); break; case BindingMode.OneTime: - throw new NotImplementedException(); + Target.GetObservable(Control.DataContextProperty).Subscribe(dataContext => + { + subject.Take(1).Subscribe(x => Target.SetValue(TargetProperty, x)); + }); + break; case BindingMode.OneWayToSource: Target.GetObservable(TargetProperty).Subscribe(subject); break; diff --git a/tests/Perspex.Markup.Xaml.UnitTests/Binding/XamlBindingTests.cs b/tests/Perspex.Markup.Xaml.UnitTests/Binding/XamlBindingTests.cs index 7955438b0b..321df1b475 100644 --- a/tests/Perspex.Markup.Xaml.UnitTests/Binding/XamlBindingTests.cs +++ b/tests/Perspex.Markup.Xaml.UnitTests/Binding/XamlBindingTests.cs @@ -53,6 +53,37 @@ namespace Perspex.Markup.Xaml.UnitTests.Binding BindingPriority.LocalValue)); } + [Fact] + public void OneTime_Binding_Should_Be_Set_Up() + { + var dataContext = new BehaviorSubject(null); + var expression = new BehaviorSubject(null); + var target = CreateTarget(dataContext: dataContext); + var binding = new XamlBinding + { + Target = target.Object, + TargetProperty = TextBox.TextProperty, + SourcePropertyPath = "Foo", + BindingMode = BindingMode.OneTime, + }; + + binding.Bind(expression); + + target.Verify(x => x.SetValue( + (PerspexProperty)TextBox.TextProperty, + null, + BindingPriority.LocalValue)); + target.ResetCalls(); + + expression.OnNext("foo"); + dataContext.OnNext(1); + + target.Verify(x => x.SetValue( + (PerspexProperty)TextBox.TextProperty, + "foo", + BindingPriority.LocalValue)); + } + [Fact] public void OneWayToSource_Binding_Should_Be_Set_Up() { @@ -101,6 +132,7 @@ namespace Perspex.Markup.Xaml.UnitTests.Binding dataContext = dataContext ?? Observable.Never().StartWith((object)null); text = text ?? Observable.Never().StartWith((string)null); + result.Setup(x => x.GetObservable(Control.DataContextProperty)).Returns(dataContext); result.Setup(x => x.GetObservable((PerspexProperty)Control.DataContextProperty)).Returns(dataContext); result.Setup(x => x.GetObservable((PerspexProperty)TextBox.TextProperty)).Returns(text); return result;