Browse Source

Initial XAML implementation of nested styles.

pull/8024/head
Steven Kirk 4 years ago
parent
commit
646ce23bb4
  1. 8
      src/Avalonia.Base/Styling/Style.cs
  2. 24
      src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlSelectorTransformer.cs
  3. 1
      tests/Avalonia.Markup.UnitTests/Parsers/SelectorGrammarTests.cs
  4. 32
      tests/Avalonia.Markup.Xaml.UnitTests/Xaml/StyleTests.cs

8
src/Avalonia.Base/Styling/Style.cs

@ -120,6 +120,14 @@ namespace Avalonia.Styling
instance.Start();
}
if (_children is not null)
{
foreach (var child in _children)
{
child.TryAttach(target, host);
}
}
return match.Result;
}

24
src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlSelectorTransformer.cs

@ -151,6 +151,14 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers
results.Add(result);
result = initialNode;
break;
case SelectorGrammar.NestingSyntax:
var parentTargetType = context.ParentNodes().OfType<AvaloniaXamlIlTargetTypeMetadataNode>().FirstOrDefault();
if (parentTargetType is null)
throw new XamlParseException($"Cannot find parent style for nested selector.", node);
result = new XamlIlNestingSelector(result, parentTargetType.TargetType.GetClrType());
break;
default:
throw new XamlParseException($"Unsupported selector grammar '{i.GetType()}'.", node);
}
@ -474,4 +482,20 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers
m => m.Name == "Or" && m.Parameters.Count == 1 && m.Parameters[0].Name.StartsWith("IReadOnlyList"));
}
}
class XamlIlNestingSelector : XamlIlSelectorNode
{
public XamlIlNestingSelector(XamlIlSelectorNode previous, IXamlType targetType)
: base(previous)
{
TargetType = targetType;
}
public override IXamlType TargetType { get; }
protected override void DoEmit(XamlEmitContext<IXamlILEmitter, XamlILNodeEmitResult> context, IXamlILEmitter codeGen)
{
EmitCall(context, codeGen,
m => m.Name == "Nesting" && m.Parameters.Count == 1);
}
}
}

1
tests/Avalonia.Markup.UnitTests/Parsers/SelectorGrammarTests.cs

@ -573,7 +573,6 @@ namespace Avalonia.Markup.UnitTests.Parsers
result);
}
[Fact]
public void Nesting_NthChild()
{

32
tests/Avalonia.Markup.Xaml.UnitTests/Xaml/StyleTests.cs

@ -617,5 +617,37 @@ namespace Avalonia.Markup.Xaml.UnitTests.Xaml
Assert.Equal(Colors.Red, ((ISolidColorBrush)foo.Background).Color);
}
}
[Fact]
public void Can_Use_Nested_Styles()
{
using (UnitTestApplication.Start(TestServices.StyledWindow))
{
var xaml = @"
<Window xmlns='https://github.com/avaloniaui'
xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'>
<Window.Styles>
<Style Selector='Border'>
<Style.Children>
<Style Selector='&amp;.foo'>
<Setter Property='Background' Value='Red'/>
</Style>
</Style.Children>
</Style>
</Window.Styles>
<StackPanel>
<Border Name='foo'/>
</StackPanel>
</Window>";
var window = (Window)AvaloniaRuntimeXamlLoader.Load(xaml);
var foo = window.FindControl<Border>("foo");
Assert.Null(foo.Background);
foo.Classes.Add("foo");
Assert.Equal(Colors.Red, ((ISolidColorBrush)foo.Background).Color);
}
}
}
}

Loading…
Cancel
Save