Browse Source

Implement OneTime binding.

pull/237/head
Steven Kirk 11 years ago
parent
commit
1064fbd186
  1. 8
      samples/BindingTest/MainWindow.paml
  2. 27
      src/Markup/Perspex.Markup.Xaml/Binding/XamlBinding.cs
  3. 32
      tests/Perspex.Markup.Xaml.UnitTests/Binding/XamlBindingTests.cs

8
samples/BindingTest/MainWindow.paml

@ -1,9 +1,9 @@
<Window xmlns="https://github.com/perspex">
<StackPanel Margin="18" Gap="4">
<TextBlock Text="{Binding SimpleBinding}"/>
<TextBox Watermark="Two Way" Text="{Binding SimpleBinding}"/>
<TextBox Watermark="One Way" Text="{Binding SimpleBinding, Mode=OneWay}"/>
<TextBox Watermark="One Time" Text="{Binding SimpleBinding, Mode=OneTime}"/>
<TextBox Watermark="One Way To Source" Text="{Binding SimpleBinding, Mode=OneWayToSource}"/>
<TextBox Watermark="Two Way" UseFloatingWatermark="True" Text="{Binding SimpleBinding}"/>
<TextBox Watermark="One Way" UseFloatingWatermark="True" Text="{Binding SimpleBinding, Mode=OneWay}"/>
<TextBox Watermark="One Time" UseFloatingWatermark="True" Text="{Binding SimpleBinding, Mode=OneTime}"/>
<TextBox Watermark="One Way To Source" UseFloatingWatermark="True" Text="{Binding SimpleBinding, Mode=OneWayToSource}"/>
</StackPanel>
</Window>

27
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<object> 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;

32
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<object>(null);
var expression = new BehaviorSubject<object>(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<object>().StartWith((object)null);
text = text ?? Observable.Never<string>().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;

Loading…
Cancel
Save