ItemContainerGenerator`1.cs 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. // Copyright (c) The Avalonia 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 Avalonia.Controls.Templates;
  5. using Avalonia.Data;
  6. namespace Avalonia.Controls.Generators
  7. {
  8. /// <summary>
  9. /// Creates containers for items and maintains a list of created containers.
  10. /// </summary>
  11. /// <typeparam name="T">The type of the container.</typeparam>
  12. public class ItemContainerGenerator<T> : ItemContainerGenerator where T : class, IControl, new()
  13. {
  14. /// <summary>
  15. /// Initializes a new instance of the <see cref="ItemContainerGenerator{T}"/> class.
  16. /// </summary>
  17. /// <param name="owner">The owner control.</param>
  18. /// <param name="contentProperty">The container's Content property.</param>
  19. /// <param name="contentTemplateProperty">The container's ContentTemplate property.</param>
  20. public ItemContainerGenerator(
  21. IControl owner,
  22. AvaloniaProperty contentProperty,
  23. AvaloniaProperty contentTemplateProperty)
  24. : base(owner)
  25. {
  26. Contract.Requires<ArgumentNullException>(owner != null);
  27. Contract.Requires<ArgumentNullException>(contentProperty != null);
  28. ContentProperty = contentProperty;
  29. ContentTemplateProperty = contentTemplateProperty;
  30. }
  31. /// <inheritdoc/>
  32. public override Type ContainerType => typeof(T);
  33. /// <summary>
  34. /// Gets the container's Content property.
  35. /// </summary>
  36. protected AvaloniaProperty ContentProperty { get; }
  37. /// <summary>
  38. /// Gets the container's ContentTemplate property.
  39. /// </summary>
  40. protected AvaloniaProperty ContentTemplateProperty { get; }
  41. /// <inheritdoc/>
  42. protected override IControl CreateContainer(object item)
  43. {
  44. var container = item as T;
  45. if (item == null)
  46. {
  47. return null;
  48. }
  49. else if (container != null)
  50. {
  51. return container;
  52. }
  53. else
  54. {
  55. var result = new T();
  56. if (ContentTemplateProperty != null)
  57. {
  58. result.SetValue(ContentTemplateProperty, ItemTemplate, BindingPriority.Style);
  59. }
  60. result.SetValue(ContentProperty, item, BindingPriority.Style);
  61. if (!(item is IControl))
  62. {
  63. result.DataContext = item;
  64. }
  65. return result;
  66. }
  67. }
  68. /// <inheritdoc/>
  69. public override bool TryRecycle(
  70. int oldIndex,
  71. int newIndex,
  72. object item,
  73. IMemberSelector selector)
  74. {
  75. var container = ContainerFromIndex(oldIndex);
  76. if (container == null)
  77. {
  78. throw new IndexOutOfRangeException("Could not recycle container: not materialized.");
  79. }
  80. var i = selector != null ? selector.Select(item) : item;
  81. container.SetValue(ContentProperty, i);
  82. if (!(item is IControl))
  83. {
  84. container.DataContext = i;
  85. }
  86. var info = MoveContainer(oldIndex, newIndex, i);
  87. RaiseRecycled(new ItemContainerEventArgs(info));
  88. return true;
  89. }
  90. }
  91. }