|
|
|
@ -1,11 +1,6 @@ |
|
|
|
// 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 System.Linq; |
|
|
|
using System.Reactive.Subjects; |
|
|
|
using Perspex.Controls.Templates; |
|
|
|
|
|
|
|
namespace Perspex.Controls.Generators |
|
|
|
@ -14,161 +9,53 @@ namespace Perspex.Controls.Generators |
|
|
|
/// Creates containers for tree items and maintains a list of created containers.
|
|
|
|
/// </summary>
|
|
|
|
/// <typeparam name="T">The type of the container.</typeparam>
|
|
|
|
public class TreeItemContainerGenerator<T> : ITreeItemContainerGenerator where T : TreeViewItem, new() |
|
|
|
public class TreeItemContainerGenerator<T> : ItemContainerGenerator<T>, ITreeItemContainerGenerator |
|
|
|
where T : class, IControl, new() |
|
|
|
{ |
|
|
|
private Dictionary<object, T> _containers = new Dictionary<object, T>(); |
|
|
|
|
|
|
|
private readonly Subject<ItemContainers> _containersInitialized = new Subject<ItemContainers>(); |
|
|
|
private ITreeItemContainerGenerator rootGenerator; |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Initializes a new instance of the <see cref="TreeItemContainerGenerator{T}"/> class.
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="owner">The owner control.</param>
|
|
|
|
public TreeItemContainerGenerator(IControl owner) |
|
|
|
{ |
|
|
|
Owner = owner; |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Gets the currently realized containers.
|
|
|
|
/// </summary>
|
|
|
|
public IEnumerable<IControl> Containers => _containers.Values; |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Signalled whenever new containers are initialized.
|
|
|
|
/// </summary>
|
|
|
|
public IObservable<ItemContainers> ContainersInitialized => _containersInitialized; |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Gets the owner control.
|
|
|
|
/// </summary>
|
|
|
|
public IControl Owner { get; } |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Creates container controls for a collection of items.
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="startingIndex">
|
|
|
|
/// The index of the first item of the data in the containing collection.
|
|
|
|
/// <param name="contentProperty">The container's Content property.</param>
|
|
|
|
/// <param name="itemsProperty">The container's Items property.</param>
|
|
|
|
/// <param name="isExpandedProperty">The container's IsExpanded property.</param>
|
|
|
|
/// <param name="rootGenerator">
|
|
|
|
/// The item container for the root of the tree, or null if this generator is itself the
|
|
|
|
/// root of the tree.
|
|
|
|
/// </param>
|
|
|
|
/// <param name="items">The items.</param>
|
|
|
|
/// <param name="selector">An optional member selector.</param>
|
|
|
|
/// <returns>The created container controls.</returns>
|
|
|
|
public IList<IControl> CreateContainers( |
|
|
|
int startingIndex, |
|
|
|
IEnumerable items, |
|
|
|
IMemberSelector selector) |
|
|
|
public TreeItemContainerGenerator( |
|
|
|
IControl owner, |
|
|
|
PerspexProperty contentProperty, |
|
|
|
PerspexProperty itemsProperty, |
|
|
|
PerspexProperty isExpandedProperty, |
|
|
|
ITreeItemContainerGenerator rootGenerator) |
|
|
|
: base(owner, contentProperty) |
|
|
|
{ |
|
|
|
Contract.Requires<ArgumentNullException>(items != null); |
|
|
|
|
|
|
|
int index = startingIndex; |
|
|
|
var result = new List<IControl>(); |
|
|
|
|
|
|
|
foreach (var item in items) |
|
|
|
{ |
|
|
|
var i = selector != null ? selector.Select(item) : item; |
|
|
|
var container = CreateContainer(i); |
|
|
|
_containers.Add(i, container); |
|
|
|
result.Add(container); |
|
|
|
} |
|
|
|
|
|
|
|
_containersInitialized.OnNext(new ItemContainers(startingIndex, result)); |
|
|
|
|
|
|
|
return result.Where(x => x != null).ToList(); |
|
|
|
ItemsProperty = itemsProperty; |
|
|
|
IsExpandedProperty = isExpandedProperty; |
|
|
|
RootGenerator = rootGenerator; |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Removes a set of created containers from the index and returns the removed controls.
|
|
|
|
/// Gets the item container for the root of the tree, or null if this generator is itself
|
|
|
|
/// the root of the tree.
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="startingIndex">
|
|
|
|
/// The index of the first item of the data in the containing collection.
|
|
|
|
/// </param>
|
|
|
|
/// <param name="items">The items.</param>
|
|
|
|
/// <returns>The removed controls.</returns>
|
|
|
|
public IList<IControl> RemoveContainers(int startingIndex, IEnumerable items) |
|
|
|
{ |
|
|
|
var result = new List<IControl>(); |
|
|
|
|
|
|
|
foreach (var item in items) |
|
|
|
{ |
|
|
|
T container; |
|
|
|
|
|
|
|
if (_containers.TryGetValue(item, out container)) |
|
|
|
{ |
|
|
|
Remove(container, result); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
return result; |
|
|
|
} |
|
|
|
public ITreeItemContainerGenerator RootGenerator { get; } |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Clears the created containers from the index and returns the removed controls.
|
|
|
|
/// Gets the item container's Items property.
|
|
|
|
/// </summary>
|
|
|
|
/// <returns>The removed controls.</returns>
|
|
|
|
public IList<IControl> ClearContainers() |
|
|
|
{ |
|
|
|
var result = _containers; |
|
|
|
_containers = new Dictionary<object, T>(); |
|
|
|
return result.Values.Cast<IControl>().ToList(); |
|
|
|
} |
|
|
|
protected PerspexProperty ItemsProperty { get; } |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Gets the container control representing the item with the specified index.
|
|
|
|
/// Gets the item container's IsExpanded property.
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="index">The index.</param>
|
|
|
|
/// <returns>The container or null if no container created.</returns>
|
|
|
|
public IControl ContainerFromIndex(int index) |
|
|
|
{ |
|
|
|
throw new NotImplementedException(); |
|
|
|
} |
|
|
|
protected PerspexProperty IsExpandedProperty { get; } |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Gets the index of the specified container control.
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="container">The container.</param>
|
|
|
|
/// <returns>The index of the container or -1 if not found.</returns>
|
|
|
|
public int IndexFromContainer(IControl container) |
|
|
|
{ |
|
|
|
throw new NotImplementedException(); |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Gets all of the generated container controls.
|
|
|
|
/// </summary>
|
|
|
|
/// <returns>The containers.</returns>
|
|
|
|
public IEnumerable<IControl> GetAllContainers() |
|
|
|
{ |
|
|
|
return _containers.Values; |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Gets the item that is contained by the specified container.
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="container">The container.</param>
|
|
|
|
/// <returns>The item.</returns>
|
|
|
|
public object ItemFromContainer(IControl container) |
|
|
|
{ |
|
|
|
return container.DataContext; |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Gets the container for the specified item
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="item">The item.</param>
|
|
|
|
/// <returns>The container.</returns>
|
|
|
|
public IControl ContainerFromItem(object item) |
|
|
|
{ |
|
|
|
T result; |
|
|
|
_containers.TryGetValue(item, out result); |
|
|
|
return result; |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Creates the container for an item.
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="item">The item.</param>
|
|
|
|
/// <returns>The created container control.</returns>
|
|
|
|
protected virtual T CreateContainer(object item) |
|
|
|
/// <inheritdoc/>
|
|
|
|
protected override IControl CreateContainer(object item) |
|
|
|
{ |
|
|
|
var container = item as T; |
|
|
|
|
|
|
|
@ -183,12 +70,11 @@ namespace Perspex.Controls.Generators |
|
|
|
else |
|
|
|
{ |
|
|
|
var template = GetTreeDataTemplate(item); |
|
|
|
var result = new T |
|
|
|
{ |
|
|
|
Header = template.Build(item), |
|
|
|
Items = template.ItemsSelector(item), |
|
|
|
IsExpanded = template.IsExpanded(item), |
|
|
|
}; |
|
|
|
var result = new T(); |
|
|
|
|
|
|
|
result.SetValue(ContentProperty, template.Build(item)); |
|
|
|
result.SetValue(ItemsProperty, template.ItemsSelector(item)); |
|
|
|
result.SetValue(IsExpandedProperty, template.IsExpanded(item)); |
|
|
|
|
|
|
|
if (!(item is IControl)) |
|
|
|
{ |
|
|
|
@ -222,29 +108,5 @@ namespace Perspex.Controls.Generators |
|
|
|
|
|
|
|
return treeTemplate; |
|
|
|
} |
|
|
|
|
|
|
|
private void Remove(T container, IList<IControl> removed) |
|
|
|
{ |
|
|
|
if (container.Items != null) |
|
|
|
{ |
|
|
|
foreach (var childItem in container.Items) |
|
|
|
{ |
|
|
|
T childContainer; |
|
|
|
|
|
|
|
if (_containers.TryGetValue(childItem, out childContainer)) |
|
|
|
{ |
|
|
|
Remove(childContainer, removed); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// TODO: Dual index.
|
|
|
|
var i = _containers.FirstOrDefault(x => x.Value == container); |
|
|
|
|
|
|
|
if (i.Key != null) |
|
|
|
{ |
|
|
|
_containers.Remove(i.Key); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|