StaticExtension.cs 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. // Copyright (c) The Perspex Project. All rights reserved.
  2. // Licensed under the MIT license. See licence.md file in the project root for full license information.
  3. using System;
  4. using System.Linq;
  5. using System.Reflection;
  6. using Glass;
  7. using OmniXaml;
  8. namespace Perspex.Markup.Xaml.MarkupExtensions
  9. {
  10. public class StaticExtension : MarkupExtension
  11. {
  12. public StaticExtension()
  13. {
  14. }
  15. public StaticExtension(string identifier)
  16. {
  17. Identifier = identifier;
  18. }
  19. public string Identifier { get; set; }
  20. public override object ProvideValue(MarkupExtensionContext markupExtensionContext)
  21. {
  22. var typeRepository = markupExtensionContext.TypeRepository;
  23. var typeAndMember = GetTypeAndMember(Identifier);
  24. var prefixAndType = GetPrefixAndType(typeAndMember.Item1);
  25. var xamlType = typeRepository.GetByPrefix(prefixAndType.Item1, prefixAndType.Item2);
  26. return GetValue(xamlType.UnderlyingType, typeAndMember.Item2);
  27. }
  28. private static Tuple<string, string> GetTypeAndMember(string s)
  29. {
  30. var parts = s.Split('.');
  31. if (parts.Length != 2)
  32. {
  33. throw new ArgumentException("Static member must be in the form Type.Member.");
  34. }
  35. return Tuple.Create(parts[0], parts[1]);
  36. }
  37. private static Tuple<string, string> GetPrefixAndType(string s)
  38. {
  39. if (s.Contains(":"))
  40. {
  41. return s.Dicotomize(':');
  42. }
  43. else
  44. {
  45. return new Tuple<string, string>(string.Empty, s);
  46. }
  47. }
  48. private object GetValue(Type type, string name)
  49. {
  50. var t = type;
  51. while (t != null)
  52. {
  53. var result = t.GetTypeInfo().DeclaredMembers.FirstOrDefault(x => x.Name == name);
  54. if (result is PropertyInfo)
  55. {
  56. var property = ((PropertyInfo)result);
  57. if (property.GetMethod.IsStatic)
  58. {
  59. return ((PropertyInfo)result).GetValue(null);
  60. }
  61. }
  62. else if (result is FieldInfo)
  63. {
  64. return ((FieldInfo)result).GetValue(null);
  65. }
  66. t = t.GetTypeInfo().BaseType;
  67. }
  68. throw new ArgumentException($"Static member '{type}.{name}' not found.");
  69. }
  70. }
  71. }