// Copyright (c) The Perspex 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; using System.Collections.Generic; using Perspex.Controls.Templates; namespace Perspex.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 Items property. /// The container's IsExpanded property. /// The container index for the tree public TreeItemContainerGenerator( IControl owner, PerspexProperty contentProperty, PerspexProperty itemsProperty, PerspexProperty isExpandedProperty, TreeContainerIndex index) : base(owner, contentProperty) { 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 PerspexProperty ItemsProperty { get; } /// /// Gets the item container's IsExpanded property. /// protected PerspexProperty 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); var result = new T(); result.SetValue(ContentProperty, template.Build(item)); result.SetValue(ItemsProperty, template.ItemsSelector(item)); if (!(item is IControl)) { result.DataContext = item; } Index.Add(item, result); return result; } } public override IEnumerable Clear() { var items = base.Clear(); Index.Remove(items); return items; } public override IEnumerable Dematerialize(int startingIndex, int count) { Index.Remove(GetContainerRange(startingIndex, count)); return base.Dematerialize(startingIndex, count); } public override IEnumerable RemoveRange(int startingIndex, int count) { Index.Remove(GetContainerRange(startingIndex, count)); return base.RemoveRange(startingIndex, count); } /// /// Gets the data template for the specified item. /// /// The item. /// The template. private ITreeDataTemplate GetTreeDataTemplate(object item) { var template = Owner.FindDataTemplate(item) ?? FuncDataTemplate.Default; var treeTemplate = template as ITreeDataTemplate ?? new FuncTreeDataTemplate(typeof(object), template.Build, x => null); return treeTemplate; } } }