Browse Source

Allow binding to anchor's DataContext.

Fixes #461.
pull/464/head
Steven Kirk 11 years ago
parent
commit
21f4570559
  1. 16
      src/Markup/Perspex.Markup.Xaml/Data/Binding.cs
  2. 2
      tests/Perspex.Markup.Xaml.UnitTests/Data/MultiBindingTests.cs
  3. 25
      tests/Perspex.Markup.Xaml.UnitTests/Xaml/BindingTests.cs
  4. 9
      tests/Perspex.Markup.Xaml.UnitTests/Xaml/NonControl.cs

16
src/Markup/Perspex.Markup.Xaml/Data/Binding.cs

@ -90,7 +90,8 @@ namespace Perspex.Markup.Xaml.Data
observer = CreateDataContexObserver(
target,
pathInfo.Path,
targetProperty == Control.DataContextProperty);
targetProperty == Control.DataContextProperty,
anchor);
}
else if (RelativeSource.Mode == RelativeSourceMode.TemplatedParent)
{
@ -161,10 +162,21 @@ namespace Perspex.Markup.Xaml.Data
private ExpressionObserver CreateDataContexObserver(
IPerspexObject target,
string path,
bool targetIsDataContext)
bool targetIsDataContext,
object anchor)
{
Contract.Requires<ArgumentNullException>(target != null);
if (!(target is IControl))
{
target = anchor as IControl;
if (target == null)
{
throw new InvalidOperationException("Cannot find a DataContext to bind to.");
}
}
if (!targetIsDataContext)
{
var update = target.GetObservable(Control.DataContextProperty)

2
tests/Perspex.Markup.Xaml.UnitTests/Data/MultiBindingTests.cs

@ -30,7 +30,7 @@ namespace Perspex.Markup.Xaml.UnitTests.Data
}
};
var target = new Mock<IPerspexObject>();
var target = new Mock<IPerspexObject>().As<IControl>();
target.Setup(x => x.GetValue(Control.DataContextProperty)).Returns(source);
var subject = binding.Initiate(target.Object, null).Subject;

25
tests/Perspex.Markup.Xaml.UnitTests/Xaml/BindingTests.cs

@ -80,6 +80,31 @@ namespace Perspex.Markup.Xaml.UnitTests.Xaml
}
}
[Fact]
public void Can_Bind_To_DataContext_Of_Anchor_On_Non_Control()
{
using (UnitTestApplication.Start(TestServices.StyledWindow))
{
var xaml = @"
<Window xmlns='https://github.com/perspex'
xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'
xmlns:local='clr-namespace:Perspex.Markup.Xaml.UnitTests.Xaml;assembly=Perspex.Markup.Xaml.UnitTests'>
<Button Name='button'>
<Button.Tag>
<local:NonControl String='{Binding Foo}'/>
</Button.Tag>
</Button>
</Window>";
var loader = new PerspexXamlLoader();
var window = (Window)loader.Load(xaml);
var button = window.FindControl<Button>("button");
button.DataContext = new { Foo = "foo" };
Assert.Equal("foo", ((NonControl)button.Tag).String);
}
}
[Fact]
public void Binding_To_Window_Works()
{

9
tests/Perspex.Markup.Xaml.UnitTests/Xaml/NonControl.cs

@ -10,10 +10,19 @@ namespace Perspex.Markup.Xaml.UnitTests.Xaml
public static readonly StyledProperty<Control> ControlProperty =
PerspexProperty.Register<NonControl, Control>("Control");
public static readonly StyledProperty<string> StringProperty =
PerspexProperty.Register<NonControl, string>("String");
public Control Control
{
get { return GetValue(ControlProperty); }
set { SetValue(ControlProperty, value); }
}
public string String
{
get { return GetValue(StringProperty); }
set { SetValue(StringProperty, value); }
}
}
}

Loading…
Cancel
Save