Browse Source

Allow setting values via ExpressionObserver.

pull/237/head
Steven Kirk 11 years ago
parent
commit
6e264dccc4
  1. 20
      src/Markup/Perspex.Markup/Binding/ExpressionObserver.cs
  2. 11
      src/Markup/Perspex.Markup/Binding/PropertyAccessorNode.cs
  3. 47
      tests/Perspex.Markup.UnitTests/Binding/ExpressionObserverTests.cs
  4. 3
      tests/Perspex.Markup.UnitTests/Perspex.Markup.UnitTests.csproj

20
src/Markup/Perspex.Markup/Binding/ExpressionObserver.cs

@ -19,6 +19,26 @@ namespace Perspex.Markup.Binding
Nodes = ExpressionNodeBuilder.Build(expression);
}
public bool SetValue(object value)
{
var last = Nodes.Last() as PropertyAccessorNode;
if (last != null)
{
try
{
IncrementCount();
return last.SetValue(value);
}
finally
{
DecrementCount();
}
}
return false;
}
public object Root { get; }
public IList<ExpressionNode> Nodes { get; }

11
src/Markup/Perspex.Markup/Binding/PropertyAccessorNode.cs

@ -16,6 +16,17 @@ namespace Perspex.Markup.Binding
PropertyName = propertyName;
}
public bool SetValue(object value)
{
if (_propertyInfo != null)
{
_propertyInfo.SetValue(Target, value);
return true;
}
return false;
}
public string PropertyName { get; }
protected override void SubscribeAndUpdate(object target)

47
tests/Perspex.Markup.UnitTests/Binding/ExpressionObserverTests.cs

@ -142,6 +142,53 @@ namespace Perspex.Markup.UnitTests.Binding
Assert.Equal(0, old.SubscriptionCount);
}
[Fact]
public void SetValue_Should_Set_Simple_Property_Value()
{
var data = new Class1 { Foo = "foo" };
var target = new ExpressionObserver(data, "Foo");
Assert.True(target.SetValue("bar"));
Assert.Equal("bar", data.Foo);
}
[Fact]
public void SetValue_Should_Set_Property_At_The_End_Of_Chain()
{
var data = new Class1 { Next = new Class2 { Bar = "bar" } };
var target = new ExpressionObserver(data, "Next.Bar");
Assert.True(target.SetValue("baz"));
Assert.Equal("baz", ((Class2)data.Next).Bar);
}
[Fact]
public void SetValue_Should_Return_False_For_Missing_Property()
{
var data = new Class1 { Next = new WithoutBar()};
var target = new ExpressionObserver(data, "Next.Bar");
Assert.False(target.SetValue("baz"));
}
[Fact]
public void SetValue_Should_Return_False_For_Missing_Object()
{
var data = new Class1();
var target = new ExpressionObserver(data, "Next.Bar");
Assert.False(target.SetValue("baz"));
}
[Fact]
public void SetValue_Should_Throw_For_Wrong_Type()
{
var data = new Class1 { Foo = "foo" };
var target = new ExpressionObserver(data, "Foo");
Assert.Throws<ArgumentException>(() => target.SetValue(1.2));
}
private interface INext
{
int SubscriptionCount { get; }

3
tests/Perspex.Markup.UnitTests/Perspex.Markup.UnitTests.csproj

@ -86,6 +86,9 @@
<Name>Perspex.Markup</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>

Loading…
Cancel
Save