// Copyright (c) The Avalonia Project. All rights reserved. // Licensed under the MIT license. See licence.md file in the project root for full license information. using System; using System.Collections.Generic; using Avalonia.Controls.Templates; using Avalonia.Data; namespace Avalonia.Controls.Generators { /// /// Creates containers for tree items and maintains a list of created containers. /// /// The type of the container. public class TreeItemContainerGenerator : ItemContainerGenerator, ITreeItemContainerGenerator where T : class, IControl, new() { /// /// Initializes a new instance of the class. /// /// The owner control. /// The container's Content property. /// The container's ContentTemplate property. /// The container's Items property. /// The container's IsExpanded property. /// The container index for the tree public TreeItemContainerGenerator( IControl owner, AvaloniaProperty contentProperty, AvaloniaProperty contentTemplateProperty, AvaloniaProperty itemsProperty, AvaloniaProperty isExpandedProperty, TreeContainerIndex index) : base(owner, contentProperty, contentTemplateProperty) { Contract.Requires(owner != null); Contract.Requires(contentProperty != null); Contract.Requires(itemsProperty != null); Contract.Requires(isExpandedProperty != null); Contract.Requires(index != null); ItemsProperty = itemsProperty; IsExpandedProperty = isExpandedProperty; Index = index; } /// /// Gets the container index for the tree. /// public TreeContainerIndex Index { get; } /// /// Gets the item container's Items property. /// protected AvaloniaProperty ItemsProperty { get; } /// /// Gets the item container's IsExpanded property. /// protected AvaloniaProperty IsExpandedProperty { get; } /// protected override IControl CreateContainer(object item) { var container = item as T; if (item == null) { return null; } else if (container != null) { Index.Add(item, container); return container; } else { var template = GetTreeDataTemplate(item, ItemTemplate); var result = new T(); result.SetValue(ContentProperty, template.Build(item), BindingPriority.Style); var itemsSelector = template.ItemsSelector(item); if (itemsSelector != null) { BindingOperations.Apply(result, ItemsProperty, itemsSelector, null); } if (!(item is IControl)) { result.DataContext = item; } NameScope.SetNameScope((Control)(object)result, new NameScope()); Index.Add(item, result); return result; } } public override IEnumerable Clear() { var items = base.Clear(); Index.Remove(0, items); return items; } public override IEnumerable Dematerialize(int startingIndex, int count) { Index.Remove(startingIndex, GetContainerRange(startingIndex, count)); return base.Dematerialize(startingIndex, count); } public override IEnumerable RemoveRange(int startingIndex, int count) { Index.Remove(startingIndex, GetContainerRange(startingIndex, count)); return base.RemoveRange(startingIndex, count); } public override bool TryRecycle(int oldIndex, int newIndex, object item, IMemberSelector selector) { return false; } private ITreeDataTemplate GetTreeDataTemplate(object item, IDataTemplate primary) { var template = Owner.FindDataTemplate(item, primary) ?? FuncDataTemplate.Default; var treeTemplate = template as ITreeDataTemplate ?? new FuncTreeDataTemplate(typeof(object), template.Build, x => null); return treeTemplate; } } }