Skip to content

Commit

Permalink
Merge pull request #11575 from workgroupengineering/features/Issue_11334
Browse files Browse the repository at this point in the history
feat: Also allows using string instead of {x:Type} in ControlTemplate.TargetType
  • Loading branch information
maxkatz6 authored Aug 31, 2023
2 parents 0f93224 + c428ff3 commit 05d348b
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 20 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System.Linq;
using XamlX.Ast;
using XamlX.Transform;
using XamlX.Transform.Transformers;
using XamlX.TypeSystem;

namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers
Expand All @@ -22,26 +23,19 @@ public IXamlAstNode Transform(AstTransformationContext context, IXamlAstNode nod
IXamlAstTypeReference targetType;

var templatableBaseType = context.Configuration.TypeSystem.GetType("Avalonia.Controls.Control");

if ((tt?.Values.FirstOrDefault() is XamlTypeExtensionNode tn))
{
targetType = tn.Value;
}
else

targetType = tt?.Values.FirstOrDefault() switch
{
var parentScope = context.ParentNodes().OfType<AvaloniaXamlIlTargetTypeMetadataNode>()
.FirstOrDefault();
if (parentScope?.ScopeType == AvaloniaXamlIlTargetTypeMetadataNode.ScopeTypes.Style)
targetType = parentScope.TargetType;
else if (context.ParentNodes().Skip(1).FirstOrDefault() is XamlAstObjectNode directParentNode
&& templatableBaseType.IsAssignableFrom(directParentNode.Type.GetClrType()))
targetType = directParentNode.Type;
else
targetType = new XamlAstClrTypeReference(node,
templatableBaseType, false);
}


XamlTypeExtensionNode tn => tn.Value,
XamlAstTextNode textNode => TypeReferenceResolver.ResolveType(context, textNode.Text, false, textNode, true),
_ when context.ParentNodes()
.OfType<AvaloniaXamlIlTargetTypeMetadataNode>()
.FirstOrDefault() is { ScopeType: AvaloniaXamlIlTargetTypeMetadataNode.ScopeTypes.Style } parentScope => parentScope.TargetType,
_ when context.ParentNodes().Skip(1).FirstOrDefault() is XamlAstObjectNode directParentNode
&& templatableBaseType.IsAssignableFrom(directParentNode.Type.GetClrType()) => directParentNode.Type,
_ => new XamlAstClrTypeReference(node,
templatableBaseType, false)
};

return new AvaloniaXamlIlTargetTypeMetadataNode(on, targetType,
AvaloniaXamlIlTargetTypeMetadataNode.ScopeTypes.ControlTemplate);
Expand All @@ -59,7 +53,7 @@ public enum ScopeTypes
ControlTemplate,
Transitions
}

public AvaloniaXamlIlTargetTypeMetadataNode(IXamlAstValueNode value, IXamlAstTypeReference targetType,
ScopeTypes type)
: base(value, value)
Expand Down
18 changes: 18 additions & 0 deletions tests/Avalonia.Markup.Xaml.UnitTests/Xaml/ControlTemplateTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,24 @@ public void ControlTemplate_With_TargetType_Is_Operational()
Assert.IsType(typeof(ContentPresenter), template.Build(new ContentControl()).Result);
}

[Fact]
public void ControlTemplate_With_String_TargetType()
{
var xaml = @"
<ControlTemplate xmlns='https://github.com/avaloniaui'
xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'
TargetType='ContentControl'>
<ContentPresenter Content='{TemplateBinding Content}' />
</ControlTemplate>
";
var template = AvaloniaRuntimeXamlLoader.Parse<ControlTemplate>(xaml);

Assert.Equal(typeof(ContentControl), template.TargetType);

Assert.IsType(typeof(ContentPresenter), template.Build(new ContentControl()).Result);
}


[Fact]
public void ControlTemplate_With_Panel_Children_Are_Added()
{
Expand Down

0 comments on commit 05d348b

Please sign in to comment.