Browse Source
They were already available as {Type} and {Static} but these are
non-standard and should be removed in future.
pull/665/head
4 changed files with 138 additions and 0 deletions
@ -0,0 +1,86 @@ |
|||||
|
// 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; |
||||
|
using System.Linq; |
||||
|
using System.Reflection; |
||||
|
using OmniXaml; |
||||
|
using Glass.Core; |
||||
|
|
||||
|
namespace Avalonia.Markup.Xaml.MarkupExtensions.Standard |
||||
|
{ |
||||
|
public class StaticExtension : MarkupExtension |
||||
|
{ |
||||
|
public StaticExtension() |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
public StaticExtension(string identifier) |
||||
|
{ |
||||
|
Identifier = identifier; |
||||
|
} |
||||
|
|
||||
|
public string Identifier { get; set; } |
||||
|
|
||||
|
public override object ProvideValue(MarkupExtensionContext markupExtensionContext) |
||||
|
{ |
||||
|
var typeRepository = markupExtensionContext.ValueContext.TypeRepository; |
||||
|
var typeAndMember = GetTypeAndMember(Identifier); |
||||
|
var prefixAndType = GetPrefixAndType(typeAndMember.Item1); |
||||
|
var xamlType = typeRepository.GetByPrefix(prefixAndType.Item1, prefixAndType.Item2); |
||||
|
return GetValue(xamlType.UnderlyingType, typeAndMember.Item2); |
||||
|
} |
||||
|
|
||||
|
private static Tuple<string, string> GetTypeAndMember(string s) |
||||
|
{ |
||||
|
var parts = s.Split('.'); |
||||
|
|
||||
|
if (parts.Length != 2) |
||||
|
{ |
||||
|
throw new ArgumentException("Static member must be in the form Type.Member."); |
||||
|
} |
||||
|
|
||||
|
return Tuple.Create(parts[0], parts[1]); |
||||
|
} |
||||
|
|
||||
|
private static Tuple<string, string> GetPrefixAndType(string s) |
||||
|
{ |
||||
|
if (s.Contains(":")) |
||||
|
{ |
||||
|
return s.Dicotomize(':'); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
return new Tuple<string, string>(string.Empty, s); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private object GetValue(Type type, string name) |
||||
|
{ |
||||
|
var t = type; |
||||
|
|
||||
|
while (t != null) |
||||
|
{ |
||||
|
var result = t.GetTypeInfo().DeclaredMembers.FirstOrDefault(x => x.Name == name); |
||||
|
|
||||
|
if (result is PropertyInfo) |
||||
|
{ |
||||
|
var property = ((PropertyInfo)result); |
||||
|
|
||||
|
if (property.GetMethod.IsStatic) |
||||
|
{ |
||||
|
return ((PropertyInfo)result).GetValue(null); |
||||
|
} |
||||
|
} |
||||
|
else if (result is FieldInfo) |
||||
|
{ |
||||
|
return ((FieldInfo)result).GetValue(null); |
||||
|
} |
||||
|
|
||||
|
t = t.GetTypeInfo().BaseType; |
||||
|
} |
||||
|
|
||||
|
throw new ArgumentException($"Static member '{type}.{name}' not found."); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,49 @@ |
|||||
|
// 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; |
||||
|
using OmniXaml; |
||||
|
using OmniXaml.Attributes; |
||||
|
using OmniXaml.Typing; |
||||
|
using Glass.Core; |
||||
|
|
||||
|
namespace Avalonia.Markup.Xaml.MarkupExtensions.Standard |
||||
|
{ |
||||
|
[ContentProperty("TargetType")] |
||||
|
public class TypeExtension : MarkupExtension |
||||
|
{ |
||||
|
public Type Type { get; set; } |
||||
|
|
||||
|
public TypeExtension() |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
public TypeExtension(Type type) |
||||
|
{ |
||||
|
Type = type; |
||||
|
} |
||||
|
|
||||
|
public string TypeName { get; set; } |
||||
|
|
||||
|
private Type ResolveFromString(string type, ITypeRepository typeRepository) |
||||
|
{ |
||||
|
Guard.ThrowIfNull(type, nameof(type)); |
||||
|
|
||||
|
var split = type.Split(':'); |
||||
|
var prefix = split.Length == 1 ? split[0] : null; |
||||
|
var typeName = split.Length == 1 ? split[1] : split[0]; |
||||
|
var xamlType = typeRepository.GetByPrefix(prefix, typeName); |
||||
|
return xamlType.UnderlyingType; |
||||
|
} |
||||
|
|
||||
|
public override object ProvideValue(MarkupExtensionContext markupExtensionContext) |
||||
|
{ |
||||
|
if (Type != null) |
||||
|
{ |
||||
|
return Type; |
||||
|
} |
||||
|
|
||||
|
return ResolveFromString(TypeName, markupExtensionContext.ValueContext.TypeRepository); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue