ItemTemplateWrapper.cs 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. // This source file is adapted from the WinUI project.
  2. // (https://github.com/microsoft/microsoft-ui-xaml)
  3. //
  4. // Licensed to The Avalonia Project under MIT License, courtesy of The .NET Foundation.
  5. using Avalonia.Controls.Templates;
  6. namespace Avalonia.Controls
  7. {
  8. internal class ItemTemplateWrapper : IElementFactory
  9. {
  10. private readonly IDataTemplate _dataTemplate;
  11. public ItemTemplateWrapper(IDataTemplate dataTemplate) => _dataTemplate = dataTemplate;
  12. public bool SupportsRecycling => false;
  13. public IControl Build(object param) => GetElement(null, param);
  14. public bool Match(object data) => _dataTemplate.Match(data);
  15. public IControl GetElement(ElementFactoryGetArgs args)
  16. {
  17. return GetElement(args.Parent, args.Data);
  18. }
  19. public void RecycleElement(ElementFactoryRecycleArgs args)
  20. {
  21. RecycleElement(args.Parent, args.Element);
  22. }
  23. private IControl GetElement(IControl parent, object data)
  24. {
  25. var selectedTemplate = _dataTemplate;
  26. var recyclePool = RecyclePool.GetPoolInstance(selectedTemplate);
  27. IControl element = null;
  28. if (recyclePool != null)
  29. {
  30. // try to get an element from the recycle pool.
  31. element = recyclePool.TryGetElement(string.Empty, parent);
  32. }
  33. if (element == null)
  34. {
  35. // no element was found in recycle pool, create a new element
  36. element = selectedTemplate.Build(data);
  37. // Associate template with element
  38. element.SetValue(RecyclePool.OriginTemplateProperty, selectedTemplate);
  39. }
  40. return element;
  41. }
  42. private void RecycleElement(IControl parent, IControl element)
  43. {
  44. var selectedTemplate = _dataTemplate;
  45. var recyclePool = RecyclePool.GetPoolInstance(selectedTemplate);
  46. if (recyclePool == null)
  47. {
  48. // No Recycle pool in the template, create one.
  49. recyclePool = new RecyclePool();
  50. RecyclePool.SetPoolInstance(selectedTemplate, recyclePool);
  51. }
  52. recyclePool.PutElement(element, "" /* key */, parent);
  53. }
  54. }
  55. }