TreeDataTemplate.cs 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. using System;
  2. using System.Diagnostics.CodeAnalysis;
  3. using Avalonia.Controls;
  4. using Avalonia.Controls.Templates;
  5. using Avalonia.Data;
  6. using Avalonia.Data.Core;
  7. using Avalonia.Markup.Parsers;
  8. using Avalonia.Markup.Xaml.MarkupExtensions;
  9. using Avalonia.Metadata;
  10. namespace Avalonia.Markup.Xaml.Templates
  11. {
  12. public class TreeDataTemplate : ITreeDataTemplate, ITypedDataTemplate
  13. {
  14. [DataType]
  15. public Type? DataType { get; set; }
  16. [Content]
  17. [TemplateContent]
  18. public object? Content { get; set; }
  19. [AssignBinding]
  20. public BindingBase? ItemsSource { get; set; }
  21. public bool Match(object? data)
  22. {
  23. if (DataType == null)
  24. {
  25. return true;
  26. }
  27. else
  28. {
  29. return DataType.IsInstanceOfType(data);
  30. }
  31. }
  32. [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "If ItemsSource is a CompiledBinding, then path members will be preserver")]
  33. public InstancedBinding? ItemsSelector(object item)
  34. {
  35. if (ItemsSource != null)
  36. {
  37. var obs = ItemsSource switch
  38. {
  39. Binding reflection => ExpressionObserverBuilder.Build(item, reflection.Path),
  40. CompiledBindingExtension compiled => new ExpressionObserver(item, compiled.Path.BuildExpression(false)),
  41. _ => throw new InvalidOperationException("TreeDataTemplate currently only supports Binding and CompiledBindingExtension!")
  42. };
  43. return InstancedBinding.OneWay(obs, BindingPriority.Style);
  44. }
  45. return null;
  46. }
  47. public Control? Build(object? data)
  48. {
  49. var visualTreeForItem = TemplateContent.Load(Content)?.Control;
  50. if (visualTreeForItem != null)
  51. {
  52. visualTreeForItem.DataContext = data;
  53. }
  54. return visualTreeForItem;
  55. }
  56. }
  57. }