Browse Source

Add support for Source in binding.

Closes #318.
pull/404/head
Steven Kirk 10 years ago
parent
commit
f5d5d2aebe
  1. 50
      src/Markup/Perspex.Markup.Xaml/Data/Binding.cs
  2. 1
      src/Markup/Perspex.Markup.Xaml/MarkupExtensions/BindingExtension.cs
  3. 39
      tests/Perspex.Markup.Xaml.UnitTests/Data/BindingTests_Source.cs
  4. 1
      tests/Perspex.Markup.Xaml.UnitTests/Perspex.Markup.Xaml.UnitTests.csproj

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

@ -36,6 +36,11 @@ namespace Perspex.Markup.Xaml.Data
/// </summary>
public BindingMode Mode { get; set; }
/// <summary>
/// Gets or sets the binding path.
/// </summary>
public string Path { get; set; }
/// <summary>
/// Gets or sets the binding priority.
/// </summary>
@ -47,9 +52,9 @@ namespace Perspex.Markup.Xaml.Data
public RelativeSource RelativeSource { get; set; }
/// <summary>
/// Gets or sets the binding path.
/// Gets or sets the source for the binding.
/// </summary>
public string Path { get; set; }
public object Source { get; set; }
/// <summary>
/// Creates a subject that can be used to get and set the value of the binding.
@ -67,7 +72,6 @@ namespace Perspex.Markup.Xaml.Data
ValidateState(pathInfo);
ExpressionObserver observer;
var targetIsDataContext = targetProperty == Control.DataContextProperty;
if (pathInfo.ElementName != null || ElementName != null)
{
@ -76,18 +80,20 @@ namespace Perspex.Markup.Xaml.Data
pathInfo.ElementName ?? ElementName,
pathInfo.Path);
}
else if (Source != null)
{
observer = CreateSourceObserver(Source, pathInfo.Path);
}
else if (RelativeSource == null || RelativeSource.Mode == RelativeSourceMode.DataContext)
{
observer = CreateDataContexObserver(
target,
pathInfo.Path,
targetIsDataContext);
targetProperty == Control.DataContextProperty);
}
else if (RelativeSource.Mode == RelativeSourceMode.TemplatedParent)
{
observer = CreateTemplatedParentObserver(
target,
pathInfo.Path);
observer = CreateTemplatedParentObserver(target, pathInfo.Path);
}
else
{
@ -178,6 +184,23 @@ namespace Perspex.Markup.Xaml.Data
}
}
private ExpressionObserver CreateElementObserver(IControl target, string elementName, string path)
{
Contract.Requires<ArgumentNullException>(target != null);
var result = new ExpressionObserver(
ControlLocator.Track(target, elementName),
path);
return result;
}
private ExpressionObserver CreateSourceObserver(object source, string path)
{
Contract.Requires<ArgumentNullException>(source != null);
return new ExpressionObserver(source, path);
}
private ExpressionObserver CreateTemplatedParentObserver(
IPerspexObject target,
string path)
@ -196,19 +219,6 @@ namespace Perspex.Markup.Xaml.Data
return result;
}
private ExpressionObserver CreateElementObserver(
IControl target,
string elementName,
string path)
{
Contract.Requires<ArgumentNullException>(target != null);
var result = new ExpressionObserver(
ControlLocator.Track(target, elementName),
path);
return result;
}
private IControl LookupNamedControl(IControl target)
{
Contract.Requires<ArgumentNullException>(target != null);

1
src/Markup/Perspex.Markup.Xaml/MarkupExtensions/BindingExtension.cs

@ -37,5 +37,6 @@ namespace Perspex.Markup.Xaml.MarkupExtensions
public BindingMode Mode { get; set; }
public string Path { get; set; }
public BindingPriority Priority { get; set; } = BindingPriority.LocalValue;
public object Source { get; set; }
}
}

39
tests/Perspex.Markup.Xaml.UnitTests/Data/BindingTests_Source.cs

@ -0,0 +1,39 @@
// Copyright (c) The Perspex Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
using Moq;
using Perspex.Controls;
using Perspex.Data;
using Perspex.Markup.Data;
using Perspex.Markup.Xaml.Data;
using ReactiveUI;
using Xunit;
namespace Perspex.Markup.Xaml.UnitTests.Data
{
public class BindingTests_Source
{
[Fact]
public void Source_Should_Be_Used()
{
var source = new Source { Foo = "foo" };
var binding = new Binding { Source = source, Path = "Foo" };
var target = new TextBlock();
target.Bind(TextBlock.TextProperty, binding);
Assert.Equal(target.Text, "foo");
}
public class Source : ReactiveObject
{
private string _foo;
public string Foo
{
get { return _foo; }
set { this.RaiseAndSetIfChanged(ref _foo, value); }
}
}
}
}

1
tests/Perspex.Markup.Xaml.UnitTests/Perspex.Markup.Xaml.UnitTests.csproj

@ -85,6 +85,7 @@
<Otherwise />
</Choose>
<ItemGroup>
<Compile Include="Data\BindingTests_Source.cs" />
<Compile Include="Data\BindingTests_ElementName.cs" />
<Compile Include="Data\MultiBindingTests.cs" />
<Compile Include="Data\BindingTests_TemplatedParent.cs" />

Loading…
Cancel
Save