AvaloniaXamlIlDesignPropertiesTransformer.cs 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. using System.Collections.Generic;
  2. using System.Linq;
  3. using XamlX;
  4. using XamlX.Ast;
  5. using XamlX.Transform;
  6. namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers
  7. {
  8. class AvaloniaXamlIlDesignPropertiesTransformer : IXamlAstTransformer
  9. {
  10. public bool IsDesignMode { get; set; }
  11. private static Dictionary<string, string> DesignDirectives = new Dictionary<string, string>()
  12. {
  13. ["DataContext"] = "DataContext",
  14. ["DesignWidth"] = "Width", ["DesignHeight"] = "Height", ["PreviewWith"] = "PreviewWith"
  15. };
  16. private const string AvaloniaNs = "https://github.com/avaloniaui";
  17. public IXamlAstNode Transform(AstTransformationContext context, IXamlAstNode node)
  18. {
  19. if (node is XamlAstObjectNode on)
  20. {
  21. for (var c=0; c<on.Children.Count;)
  22. {
  23. var ch = on.Children[c];
  24. if (ch is XamlAstXmlDirective directive
  25. && directive.Namespace == XamlNamespaces.Blend2008
  26. && DesignDirectives.TryGetValue(directive.Name, out var mapTo))
  27. {
  28. if (!IsDesignMode)
  29. // Just remove it from AST in non-design mode
  30. on.Children.RemoveAt(c);
  31. else
  32. {
  33. // Map to an actual property in `Design` class
  34. on.Children[c] = new XamlAstXamlPropertyValueNode(ch,
  35. new XamlAstNamePropertyReference(ch,
  36. new XamlAstXmlTypeReference(ch, AvaloniaNs, "Design"),
  37. mapTo, on.Type), directive.Values, true);
  38. c++;
  39. }
  40. }
  41. // Remove all "Design" attached properties in non-design mode
  42. else if (
  43. !IsDesignMode
  44. && ch is XamlAstXamlPropertyValueNode pv
  45. && pv.Property is XamlAstNamePropertyReference pref
  46. && pref.DeclaringType is XamlAstXmlTypeReference dref
  47. && dref.XmlNamespace == AvaloniaNs && dref.Name == "Design"
  48. )
  49. {
  50. on.Children.RemoveAt(c);
  51. }
  52. else
  53. c++;
  54. }
  55. }
  56. return node;
  57. }
  58. }
  59. }