Skip to content

Commit

Permalink
Handle $self in compiled binding in multibinding. (AvaloniaUI#14935)
Browse files Browse the repository at this point in the history
  • Loading branch information
appel1 authored Mar 15, 2024
1 parent 5537e97 commit 84b06b2
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,12 @@ propertyNode.Values[0] is XamlAstConstructableObjectNode obj &&
};

var selfType = context.ParentNodes().OfType<XamlAstConstructableObjectNode>().First().Type.GetClrType();


if (context.GetAvaloniaTypes().MultiBinding.IsAssignableFrom(selfType))
{
selfType = context.ParentNodes().OfType<XamlAstConstructableObjectNode>().Skip(1).First().Type.GetClrType();
}

// When using self bindings with setters we need to change target type to resolved selector type.
if (context.GetAvaloniaTypes().SetterBase.IsAssignableFrom(selfType))
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ class AvaloniaXamlIlWellKnownTypes
public IXamlMethod AvaloniaObjectSetStyledPropertyValue { get; }
public IXamlType AvaloniaAttachedPropertyT { get; }
public IXamlType IBinding { get; }
public IXamlType MultiBinding { get; }
public IXamlMethod AvaloniaObjectBindMethod { get; }
public IXamlMethod AvaloniaObjectSetValueMethod { get; }
public IXamlType IDisposable { get; }
Expand Down Expand Up @@ -140,6 +141,7 @@ public AvaloniaXamlIlWellKnownTypes(TransformerConfiguration cfg)
&& m.Parameters[0].Name == "StyledProperty`1"
&& m.Parameters[2].Equals(BindingPriority));
IBinding = cfg.TypeSystem.GetType("Avalonia.Data.IBinding");
MultiBinding = cfg.TypeSystem.GetType("Avalonia.Data.MultiBinding");
IDisposable = cfg.TypeSystem.GetType("System.IDisposable");
ICommand = cfg.TypeSystem.GetType("System.Windows.Input.ICommand");
Transitions = cfg.TypeSystem.GetType("Avalonia.Animation.Transitions");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1692,6 +1692,74 @@ public void Binds_To_RelativeSource_Self()
}
}

[Theory]
[InlineData(false)]
[InlineData(true)]
public void Binds_To_RelativeSource_Self_In_MultiBinding(bool compileBindings)
{
using (UnitTestApplication.Start(TestServices.StyledWindow))
{
var xaml = $@"
<Window xmlns='https://github.com/avaloniaui'
xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'
x:CompileBindings='{compileBindings}'>
<StackPanel>
<TextBlock Name='textBlock'>
<TextBlock.Text>
<MultiBinding StringFormat=""{{}} $self = {{0}}, $parent = {{1}}"">
<Binding Path=""$self.FontStyle""/>
<Binding Path=""$parent.Orientation""/>
</MultiBinding>
</TextBlock.Text>
</TextBlock>
</StackPanel>
</Window>";
var window = (Window)AvaloniaRuntimeXamlLoader.Load(xaml);
var textBlock = window.GetControl<TextBlock>("textBlock");

var dataContext = new TestDataContext();
window.DataContext = dataContext;

Assert.Equal(" $self = Normal, $parent = Vertical"
, textBlock.GetValue(TextBlock.TextProperty));
}
}

[Theory]
[InlineData(false)]
[InlineData(true)]
public void Binds_To_RelativeSource_Self_In_MultiBinding_In_Style(bool compileBindings)
{
using (UnitTestApplication.Start(TestServices.StyledWindow))
{
var xaml = $@"
<Window xmlns='https://github.com/avaloniaui'
xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'
x:CompileBindings='{compileBindings}'>
<Window.Styles>
<Style Selector='TextBlock'>
<Setter Property='Text'>
<MultiBinding StringFormat=""{{}} $self = {{0}}"">
<Binding Path=""$self.FontStyle""/>
</MultiBinding>
</Setter>
</Style>
</Window.Styles>
<StackPanel>
<TextBlock Name='textBlock'/>
</StackPanel>
</Window>";
var window = (Window)AvaloniaRuntimeXamlLoader.Load(xaml);
var textBlock = window.GetControl<TextBlock>("textBlock");

var dataContext = new TestDataContext();
window.DataContext = dataContext;

Assert.Equal(" $self = Normal"
, textBlock.GetValue(TextBlock.TextProperty));
}
}

[Fact]
public void SupportsMethodBindingAsDelegate()
{
Expand Down

0 comments on commit 84b06b2

Please sign in to comment.