// 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 System.Linq; namespace Avalonia.Controls.Generators { /// /// Maintains an index of all item containers currently materialized by a . /// /// /// Each has its own /// that maintains the list of its direct children, but they also share an instance of this /// class in their property which tracks /// the containers materialized for the entire tree. /// public class TreeContainerIndex { private readonly Dictionary _itemToContainer = new Dictionary(); private readonly Dictionary _containerToItem = new Dictionary(); /// /// Signaled whenever new containers are materialized. /// public event EventHandler Materialized; /// /// Event raised whenever containers are dematerialized. /// public event EventHandler Dematerialized; /// /// Gets the currently materialized containers. /// public IEnumerable Containers => _containerToItem.Keys; /// /// Gets the items of currently materialized containers. /// public IEnumerable Items => _containerToItem.Values; /// /// Adds an entry to the index. /// /// The item. /// The item container. public void Add(object item, IControl container) { _itemToContainer.Add(item, container); _containerToItem.Add(container, item); Materialized?.Invoke( this, new ItemContainerEventArgs(new ItemContainerInfo(container, item, 0))); } /// /// Removes a container from the index. /// /// The item container. public void Remove(IControl container) { var item = _containerToItem[container]; _containerToItem.Remove(container); _itemToContainer.Remove(item); Dematerialized?.Invoke( this, new ItemContainerEventArgs(new ItemContainerInfo(container, item, 0))); } /// /// Removes a set of containers from the index. /// /// The index of the first item. /// The item containers. public void Remove(int startingIndex, IEnumerable containers) { foreach (var container in containers) { var item = _containerToItem[container.ContainerControl]; _containerToItem.Remove(container.ContainerControl); _itemToContainer.Remove(item); } Dematerialized?.Invoke( this, new ItemContainerEventArgs(startingIndex, containers.ToList())); } /// /// Gets the container for an item. /// /// The item. /// The container, or null of not found. public IControl ContainerFromItem(object item) { if (item != null) { _itemToContainer.TryGetValue(item, out var result); return result; } return null; } /// /// Gets the item for a container. /// /// The container. /// The item, or null of not found. public object ItemFromContainer(IControl container) { if (container != null) { _containerToItem.TryGetValue(container, out var result); return result; } return null; } } }