committed by
Andrey Kunchev
17 changed files with 596 additions and 122 deletions
@ -0,0 +1,15 @@ |
|||||
|
// Copyright (c) The Avalonia Project. All rights reserved.
|
||||
|
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
||||
|
|
||||
|
using System; |
||||
|
|
||||
|
namespace Avalonia.Metadata |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Defines the ambient class/property
|
||||
|
/// </summary>
|
||||
|
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property, Inherited = true)] |
||||
|
public class AmbientAttribute : Attribute |
||||
|
{ |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,29 @@ |
|||||
|
using Avalonia.Markup.Xaml.Templates; |
||||
|
using avm = Avalonia.Metadata; |
||||
|
using pm = Portable.Xaml.Markup; |
||||
|
|
||||
|
namespace Avalonia.Markup.Xaml.PortableXaml |
||||
|
{ |
||||
|
internal static class AttributeExtensions |
||||
|
{ |
||||
|
public static pm.XamlDeferLoadAttribute ToPortableXaml(this avm.TemplateContentAttribute attrib) |
||||
|
{ |
||||
|
if (attrib == null) |
||||
|
{ |
||||
|
return null; |
||||
|
} |
||||
|
|
||||
|
return new pm.XamlDeferLoadAttribute(typeof(TemplateLoader), typeof(TemplateContent)); |
||||
|
} |
||||
|
|
||||
|
public static pm.AmbientAttribute ToPortableXaml(this avm.AmbientAttribute attrib) |
||||
|
{ |
||||
|
if (attrib == null) |
||||
|
{ |
||||
|
return null; |
||||
|
} |
||||
|
|
||||
|
return new pm.AmbientAttribute(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,68 @@ |
|||||
|
using Avalonia.Controls; |
||||
|
using Avalonia.Data; |
||||
|
using Avalonia.Styling; |
||||
|
using Portable.Xaml.ComponentModel; |
||||
|
using Portable.Xaml.Markup; |
||||
|
using System; |
||||
|
|
||||
|
namespace Avalonia.Markup.Xaml.PortableXaml |
||||
|
{ |
||||
|
internal class XamlBinding : IBinding |
||||
|
{ |
||||
|
public static IBinding FromMarkupExtensionContext( |
||||
|
IBinding binding, |
||||
|
IServiceProvider serviceProvider) |
||||
|
{ |
||||
|
var context = (ITypeDescriptorContext)serviceProvider; |
||||
|
var pvt = context.GetService<IProvideValueTarget>(); |
||||
|
|
||||
|
if (pvt.TargetObject is IControl) return binding; |
||||
|
|
||||
|
object anchor = GetDefaultAnchor(context); |
||||
|
|
||||
|
if (anchor == null) return binding; |
||||
|
|
||||
|
return new XamlBinding(binding, anchor); |
||||
|
} |
||||
|
|
||||
|
private static object GetDefaultAnchor(ITypeDescriptorContext context) |
||||
|
{ |
||||
|
object anchor = null; |
||||
|
|
||||
|
//// The target is not a control, so we need to find an anchor that will let us look
|
||||
|
//// up named controls and style resources. First look for the closest IControl in
|
||||
|
//// the TopDownValueContext.
|
||||
|
|
||||
|
//anchor = context.TopDownValueContext.StoredInstances
|
||||
|
// .Select(x => x.Instance)
|
||||
|
// .OfType<IControl>()
|
||||
|
// .LastOrDefault();
|
||||
|
anchor = context.GetFirstAmbientValue<IControl>(); |
||||
|
|
||||
|
//// If a control was not found, then try to find the highest-level style as the XAML
|
||||
|
//// file could be a XAML file containing only styles.
|
||||
|
// anchor = context.TopDownValueContext.StoredInstances
|
||||
|
// .Select(x => x.Instance)
|
||||
|
// .OfType<IStyle>()
|
||||
|
// .FirstOrDefault();
|
||||
|
return anchor ?? context.GetLastOrDefaultAmbientValue<IStyle>(); |
||||
|
} |
||||
|
|
||||
|
private XamlBinding(IBinding binding, object anchor) |
||||
|
{ |
||||
|
Value = binding; |
||||
|
|
||||
|
Anchor = new WeakReference(anchor); |
||||
|
} |
||||
|
|
||||
|
public WeakReference Anchor { get; } |
||||
|
|
||||
|
public IBinding Value { get; } |
||||
|
|
||||
|
public InstancedBinding Initiate(IAvaloniaObject target, AvaloniaProperty targetProperty, object anchor = null, bool enableDataValidation = false) |
||||
|
{ |
||||
|
return Value.Initiate(target, targetProperty, |
||||
|
anchor ?? Anchor.Target, enableDataValidation); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue