Browse Source

Fix ElementName binding inside of control template

pull/8466/head
Max Katz 4 years ago
parent
commit
042fd47c1e
  1. 7
      src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/XamlIlBindingPathHelper.cs
  2. 32
      tests/Avalonia.Markup.Xaml.UnitTests/MarkupExtensions/CompiledBindingExtensionTests.cs

7
src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/XamlIlBindingPathHelper.cs

@ -374,6 +374,12 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions
public static IXamlType GetTargetType(IXamlAstNode namescopeRoot, string name) public static IXamlType GetTargetType(IXamlAstNode namescopeRoot, string name)
{ {
// If we start from the nested scope - skip it.
if (namescopeRoot is NestedScopeMetadataNode scope)
{
namescopeRoot = scope.Value;
}
var finder = new ScopeRegistrationFinder(name); var finder = new ScopeRegistrationFinder(name);
namescopeRoot.Visit(finder); namescopeRoot.Visit(finder);
return finder.TargetType; return finder.TargetType;
@ -399,6 +405,7 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions
IXamlAstNode IXamlAstVisitor.Visit(IXamlAstNode node) IXamlAstNode IXamlAstVisitor.Visit(IXamlAstNode node)
{ {
// Ignore name registrations, if we are inside of the nested namescope.
if (_childScopesStack.Count == 0 && node is AvaloniaNameScopeRegistrationXamlIlNode registration) if (_childScopesStack.Count == 0 && node is AvaloniaNameScopeRegistrationXamlIlNode registration)
{ {
if (registration.Name is XamlAstTextNode text && text.Text == Name) if (registration.Name is XamlAstTextNode text && text.Text == Name)

32
tests/Avalonia.Markup.Xaml.UnitTests/MarkupExtensions/CompiledBindingExtensionTests.cs

@ -641,6 +641,38 @@ namespace Avalonia.Markup.Xaml.UnitTests.MarkupExtensions
} }
} }
[Fact]
public void ResolvesElementNameInTemplate()
{
using (UnitTestApplication.Start(TestServices.StyledWindow))
{
var xaml = @"
<ContentControl xmlns='https://github.com/avaloniaui'
Content='Hello'>
<ContentControl.Styles>
<Style Selector='ContentControl'>
<Setter Property='Template'>
<ControlTemplate>
<Panel>
<TextBox Name='InnerTextBox' Text='Hello' />
<ContentPresenter Content='{CompiledBinding Text, ElementName=InnerTextBox}' />
</Panel>
</ControlTemplate>
</Setter>
</Style>
</ContentControl.Styles>
</ContentControl>";
var contentControl = AvaloniaRuntimeXamlLoader.Parse<ContentControl>(xaml);
contentControl.Measure(new Size(10, 10));
var result = contentControl.GetTemplateChildren().OfType<ContentPresenter>().First();
Assert.Equal("Hello", result.Content);
}
}
[Fact] [Fact]
public void Binds_To_Source() public void Binds_To_Source()
{ {

Loading…
Cancel
Save