10 changed files with 477 additions and 9 deletions
@ -0,0 +1,52 @@ |
|||
using System; |
|||
using Avalonia.Data.Core; |
|||
using Avalonia.VisualTree; |
|||
|
|||
namespace Avalonia.Markup.Xaml.MarkupExtensions.CompiledBindings |
|||
{ |
|||
class FindVisualAncestorNode : ExpressionNode |
|||
{ |
|||
private readonly int _level; |
|||
private readonly Type _ancestorType; |
|||
private IDisposable _subscription; |
|||
|
|||
public FindVisualAncestorNode(Type ancestorType, int level) |
|||
{ |
|||
_level = level; |
|||
_ancestorType = ancestorType; |
|||
} |
|||
|
|||
public override string Description |
|||
{ |
|||
get |
|||
{ |
|||
if (_ancestorType == null) |
|||
{ |
|||
return $"$visualparent[{_level}]"; |
|||
} |
|||
else |
|||
{ |
|||
return $"$visualparent[{_ancestorType.Name}, {_level}]"; |
|||
} |
|||
} |
|||
} |
|||
|
|||
protected override void StartListeningCore(WeakReference<object> reference) |
|||
{ |
|||
if (reference.TryGetTarget(out object target) && target is IVisual visual) |
|||
{ |
|||
_subscription = VisualLocator.Track(visual, _level, _ancestorType).Subscribe(ValueChanged); |
|||
} |
|||
else |
|||
{ |
|||
_subscription = null; |
|||
} |
|||
} |
|||
|
|||
protected override void StopListeningCore() |
|||
{ |
|||
_subscription?.Dispose(); |
|||
_subscription = null; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,52 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Text; |
|||
using XamlIl; |
|||
using XamlIl.Ast; |
|||
using XamlIl.Transform; |
|||
|
|||
namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers |
|||
{ |
|||
class AvaloniaXamlIlTransformSyntheticCompiledBindingMembers : IXamlIlAstTransformer |
|||
{ |
|||
public IXamlIlAstNode Transform(XamlIlAstTransformationContext context, IXamlIlAstNode node) |
|||
{ |
|||
if (node is XamlIlAstNamePropertyReference prop |
|||
&& prop.TargetType is XamlIlAstClrTypeReference targetRef |
|||
&& targetRef.GetClrType().Equals(context.GetAvaloniaTypes().CompiledBindingExtension)) |
|||
{ |
|||
if (prop.Name == "ElementName") |
|||
{ |
|||
return new AvaloniaSyntheticCompiledBindingProperty(node, |
|||
SyntheticCompiledBindingPropertyName.ElementName); |
|||
} |
|||
else if (prop.Name == "RelativeSource") |
|||
{ |
|||
return new AvaloniaSyntheticCompiledBindingProperty(node, |
|||
SyntheticCompiledBindingPropertyName.RelativeSource); |
|||
} |
|||
} |
|||
|
|||
return node; |
|||
} |
|||
} |
|||
|
|||
enum SyntheticCompiledBindingPropertyName |
|||
{ |
|||
ElementName, |
|||
RelativeSource |
|||
} |
|||
|
|||
class AvaloniaSyntheticCompiledBindingProperty : XamlIlAstNode, IXamlIlAstPropertyReference |
|||
{ |
|||
public SyntheticCompiledBindingPropertyName Name { get; } |
|||
|
|||
public AvaloniaSyntheticCompiledBindingProperty( |
|||
IXamlIlLineInfo lineInfo, |
|||
SyntheticCompiledBindingPropertyName name) |
|||
: base(lineInfo) |
|||
{ |
|||
Name = name; |
|||
} |
|||
} |
|||
} |
|||
Loading…
Reference in new issue