Browse Source

Merge pull request #848 from AvaloniaUI/features/relativesource-self

Added RelativeSource=Self binding mode.
pull/642/head
Steven Kirk 10 years ago
committed by GitHub
parent
commit
7b46305edb
  1. 4
      src/Markup/Avalonia.Markup.Xaml/Data/Binding.cs
  2. 1
      src/Markup/Avalonia.Markup.Xaml/Data/RelativeSource.cs
  3. 2
      src/Markup/Avalonia.Markup/Data/MarkupBindingChainException.cs
  4. 1
      tests/Avalonia.Markup.Xaml.UnitTests/Avalonia.Markup.Xaml.UnitTests.csproj
  5. 63
      tests/Avalonia.Markup.Xaml.UnitTests/Data/BindingTests_Self.cs
  6. 44
      tests/Avalonia.Markup.Xaml.UnitTests/Xaml/BindingTests.cs

4
src/Markup/Avalonia.Markup.Xaml/Data/Binding.cs

@ -115,6 +115,10 @@ namespace Avalonia.Markup.Xaml.Data
anchor,
enableDataValidation);
}
else if (RelativeSource.Mode == RelativeSourceMode.Self)
{
observer = CreateSourceObserver(target, pathInfo.Path, enableDataValidation);
}
else if (RelativeSource.Mode == RelativeSourceMode.TemplatedParent)
{
observer = CreateTemplatedParentObserver(target, pathInfo.Path);

1
src/Markup/Avalonia.Markup.Xaml/Data/RelativeSource.cs

@ -5,6 +5,7 @@ namespace Avalonia.Markup.Xaml.Data
{
public enum RelativeSourceMode
{
Self,
DataContext,
TemplatedParent,
}

2
src/Markup/Avalonia.Markup/Data/MarkupBindingChainException.cs

@ -26,7 +26,7 @@ namespace Avalonia.Markup.Data
_nodes = null;
}
public bool HasNodes => _nodes.Count > 0;
public bool HasNodes => _nodes?.Count > 0;
public void AddNode(string node) => _nodes.Add(node);
public void Commit(string expression)

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

@ -96,6 +96,7 @@
<Compile Include="Data\BindingTests_DataValidation.cs" />
<Compile Include="Data\BindingTests_Source.cs" />
<Compile Include="Data\BindingTests_ElementName.cs" />
<Compile Include="Data\BindingTests_Self.cs" />
<Compile Include="Data\MultiBindingTests.cs" />
<Compile Include="Data\BindingTests_TemplatedParent.cs" />
<Compile Include="Data\BindingTests.cs" />

63
tests/Avalonia.Markup.Xaml.UnitTests/Data/BindingTests_Self.cs

@ -0,0 +1,63 @@
// Copyright (c) The Avalonia Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
using System;
using Moq;
using Avalonia.Controls;
using Avalonia.Data;
using Avalonia.Markup.Xaml.Data;
using Avalonia.Styling;
using Xunit;
using System.Reactive.Disposables;
namespace Avalonia.Markup.Xaml.UnitTests.Data
{
public class BindingTests_Self
{
[Fact]
public void Binding_To_Property_On_Self_Should_Work()
{
var target = new TextBlock
{
Tag = "Hello World!",
[!TextBlock.TextProperty] = new Binding("Tag")
{
RelativeSource = new RelativeSource(RelativeSourceMode.Self)
},
};
Assert.Equal("Hello World!", target.Text);
}
[Fact]
public void TwoWay_Binding_To_Property_On_Self_Should_Work()
{
var target = new TextBlock
{
Tag = "Hello World!",
[!TextBlock.TextProperty] = new Binding("Tag", BindingMode.TwoWay)
{
RelativeSource = new RelativeSource(RelativeSourceMode.Self)
},
};
Assert.Equal("Hello World!", target.Text);
target.Text = "Goodbye cruel world :(";
Assert.Equal("Goodbye cruel world :(", target.Text);
}
private Mock<IControl> CreateTarget(
ITemplatedControl templatedParent = null,
string text = null)
{
var result = new Mock<IControl>();
result.Setup(x => x.GetValue(Control.TemplatedParentProperty)).Returns(templatedParent);
result.Setup(x => x.GetValue((AvaloniaProperty)Control.TemplatedParentProperty)).Returns(templatedParent);
result.Setup(x => x.GetValue((AvaloniaProperty)TextBox.TextProperty)).Returns(text);
result.Setup(x => x.Bind(It.IsAny<AvaloniaProperty>(), It.IsAny<IObservable<object>>(), It.IsAny<BindingPriority>()))
.Returns(Disposable.Empty);
return result;
}
}
}

44
tests/Avalonia.Markup.Xaml.UnitTests/Xaml/BindingTests.cs

@ -145,5 +145,49 @@ namespace Avalonia.Markup.Xaml.UnitTests.Xaml
Assert.Equal("foo", border.DataContext);
}
}
[Fact(Skip = "OmniXaml doesn't support nested markup extensions. #119")]
public void Binding_To_Self_Works()
{
using (UnitTestApplication.Start(TestServices.StyledWindow))
{
var xaml = @"
<Window xmlns='https://github.com/avaloniaui'
xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'>
<TextBlock Name='textblock' Text='{Binding Tag, RelativeSource={RelativeSource Self}}'/>
</Window>";
var loader = new AvaloniaXamlLoader();
var window = (Window)loader.Load(xaml);
var textBlock = (TextBlock)window.Content;
window.ApplyTemplate();
Assert.Equal("foo", textBlock.Text);
}
}
[Fact]
public void Longform_Binding_To_Self_Works()
{
using (UnitTestApplication.Start(TestServices.StyledWindow))
{
var xaml = @"
<Window xmlns='https://github.com/avaloniaui'
xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'>
<TextBlock Name='textblock' Tag='foo'>
<TextBlock.Text>
<Binding RelativeSource='{RelativeSource Self}' Path='Tag'/>
</TextBlock.Text>
</TextBlock>
</Window>";
var loader = new AvaloniaXamlLoader();
var window = (Window)loader.Load(xaml);
var textBlock = (TextBlock)window.Content;
window.ApplyTemplate();
Assert.Equal("foo", textBlock.Text);
}
}
}
}

Loading…
Cancel
Save