12 changed files with 610 additions and 383 deletions
@ -0,0 +1,36 @@ |
|||||
|
// -----------------------------------------------------------------------
|
||||
|
// <copyright file="ITreeItemContainerGenerator.cs" company="Steven Kirk">
|
||||
|
// Copyright 2015 MIT Licence. See licence.md for more information.
|
||||
|
// </copyright>
|
||||
|
// -----------------------------------------------------------------------
|
||||
|
|
||||
|
namespace Perspex.Controls.Generators |
||||
|
{ |
||||
|
using System.Collections.Generic; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Creates containers for tree items and maintains a list of created containers.
|
||||
|
/// </summary>
|
||||
|
public interface ITreeItemContainerGenerator : IItemContainerGenerator |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Gets all of the generated container controls.
|
||||
|
/// </summary>
|
||||
|
/// <returns>The containers.</returns>
|
||||
|
IEnumerable<IControl> GetAllContainers(); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the item that is contained by the specified container.
|
||||
|
/// </summary>
|
||||
|
/// <param name="container">The container.</param>
|
||||
|
/// <returns>The item.</returns>
|
||||
|
object ItemFromContainer(IControl container); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the container for the specified item
|
||||
|
/// </summary>
|
||||
|
/// <param name="item">The item.</param>
|
||||
|
/// <returns>The container.</returns>
|
||||
|
IControl ContainerFromItem(object item); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,30 @@ |
|||||
|
// -----------------------------------------------------------------------
|
||||
|
// <copyright file="ITreeDataTemplate.cs" company="Steven Kirk">
|
||||
|
// Copyright 2014 MIT Licence. See licence.md for more information.
|
||||
|
// </copyright>
|
||||
|
// -----------------------------------------------------------------------
|
||||
|
|
||||
|
namespace Perspex.Controls.Templates |
||||
|
{ |
||||
|
using System.Collections; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Interface representing a template used to build hierachical data.
|
||||
|
/// </summary>
|
||||
|
public interface ITreeDataTemplate : IDataTemplate |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Checks to see if the item should be initially expanded.
|
||||
|
/// </summary>
|
||||
|
/// <param name="item">The item.</param>
|
||||
|
/// <returns>True if the item should be initially expanded, otherwise false.</returns>
|
||||
|
bool IsExpanded(object item); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Selects the child items of an item.
|
||||
|
/// </summary>
|
||||
|
/// <param name="item">The item.</param>
|
||||
|
/// <returns>The child items, or null if no child items.</returns>
|
||||
|
IEnumerable ItemsSelector(object item); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,148 @@ |
|||||
|
// -----------------------------------------------------------------------
|
||||
|
// <copyright file="TreeDataTemplate.cs" company="Steven Kirk">
|
||||
|
// Copyright 2014 MIT Licence. See licence.md for more information.
|
||||
|
// </copyright>
|
||||
|
// -----------------------------------------------------------------------
|
||||
|
|
||||
|
namespace Perspex.Controls.Templates |
||||
|
{ |
||||
|
using System; |
||||
|
using System.Collections; |
||||
|
using System.Reflection; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// A template used to build hierachical data.
|
||||
|
/// </summary>
|
||||
|
public class TreeDataTemplate : DataTemplate, ITreeDataTemplate |
||||
|
{ |
||||
|
private Func<object, IEnumerable> itemsSelector; |
||||
|
|
||||
|
private Func<object, bool> isExpanded; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the <see cref="TreeDataTemplate"/> class.
|
||||
|
/// </summary>
|
||||
|
/// <param name="type">The type of data which the data template matches.</param>
|
||||
|
/// <param name="build">
|
||||
|
/// A function which when passed an object of <paramref name="type"/> returns a control.
|
||||
|
/// </param>
|
||||
|
/// <param name="itemsSelector">
|
||||
|
/// A function which when passed an object of <paramref name="type"/> returns the child
|
||||
|
/// items.
|
||||
|
/// </param>
|
||||
|
public TreeDataTemplate( |
||||
|
Type type, |
||||
|
Func<object, IControl> build, |
||||
|
Func<object, IEnumerable> itemsSelector) |
||||
|
: this(o => IsInstance(o, type), build, itemsSelector) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the <see cref="TreeDataTemplate"/> class.
|
||||
|
/// </summary>
|
||||
|
/// <param name="type">The type of data which the data template matches.</param>
|
||||
|
/// <param name="build">
|
||||
|
/// A function which when passed an object of <paramref name="type"/> returns a control.
|
||||
|
/// </param>
|
||||
|
/// <param name="itemsSelector">
|
||||
|
/// A function which when passed an object of <paramref name="type"/> returns the child
|
||||
|
/// items.
|
||||
|
/// </param>
|
||||
|
/// <param name="isExpanded">
|
||||
|
/// A function which when passed an object of <paramref name="type"/> returns the the
|
||||
|
/// initial expanded state of the node.
|
||||
|
/// </param>
|
||||
|
public TreeDataTemplate( |
||||
|
Type type, |
||||
|
Func<object, IControl> build, |
||||
|
Func<object, IEnumerable> itemsSelector, |
||||
|
Func<object, bool> isExpanded) |
||||
|
: this(o => IsInstance(o, type), build, itemsSelector, isExpanded) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the <see cref="TreeDataTemplate"/> class.
|
||||
|
/// </summary>
|
||||
|
/// <param name="match">
|
||||
|
/// A function which determines whether the data template matches the specified data.
|
||||
|
/// </param>
|
||||
|
/// <param name="build">
|
||||
|
/// A function which when passed a matching object returns a control.
|
||||
|
/// </param>
|
||||
|
/// <param name="itemsSelector">
|
||||
|
/// A function which when passed a matching object returns the child items.
|
||||
|
/// </param>
|
||||
|
public TreeDataTemplate( |
||||
|
Func<object, bool> match, |
||||
|
Func<object, IControl> build, |
||||
|
Func<object, IEnumerable> itemsSelector) |
||||
|
: this(match, build, itemsSelector, _ => false) |
||||
|
{ |
||||
|
this.itemsSelector = itemsSelector; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the <see cref="TreeDataTemplate"/> class.
|
||||
|
/// </summary>
|
||||
|
/// <param name="match">
|
||||
|
/// A function which determines whether the data template matches the specified data.
|
||||
|
/// </param>
|
||||
|
/// <param name="build">
|
||||
|
/// A function which when passed a matching object returns a control.
|
||||
|
/// </param>
|
||||
|
/// <param name="itemsSelector">
|
||||
|
/// A function which when passed a matching object returns the child items.
|
||||
|
/// </param>
|
||||
|
/// <param name="isExpanded">
|
||||
|
/// A function which when passed a matching object returns the the initial expanded state
|
||||
|
/// of the node.
|
||||
|
/// </param>
|
||||
|
public TreeDataTemplate( |
||||
|
Func<object, bool> match, |
||||
|
Func<object, IControl> build, |
||||
|
Func<object, IEnumerable> itemsSelector, |
||||
|
Func<object, bool> isExpanded) |
||||
|
: base(match, build) |
||||
|
{ |
||||
|
this.itemsSelector = itemsSelector; |
||||
|
this.isExpanded = isExpanded; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Checks to see if the item should be initially expanded.
|
||||
|
/// </summary>
|
||||
|
/// <param name="item">The item.</param>
|
||||
|
/// <returns>True if the item should be initially expanded, otherwise false.</returns>
|
||||
|
public bool IsExpanded(object item) |
||||
|
{ |
||||
|
return this?.isExpanded(item) ?? false; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Selects the child items of an item.
|
||||
|
/// </summary>
|
||||
|
/// <param name="item">The item.</param>
|
||||
|
/// <returns>The child items, or null if no child items.</returns>
|
||||
|
public IEnumerable ItemsSelector(object item) |
||||
|
{ |
||||
|
return this?.itemsSelector(item); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Determines of an object is of the specified type.
|
||||
|
/// </summary>
|
||||
|
/// <param name="o">The object.</param>
|
||||
|
/// <param name="t">The type.</param>
|
||||
|
/// <returns>
|
||||
|
/// True if <paramref name="o"/> is of type <paramref name="t"/>, otherwise false.
|
||||
|
/// </returns>
|
||||
|
private static bool IsInstance(object o, Type t) |
||||
|
{ |
||||
|
return (o != null) ? |
||||
|
t.GetTypeInfo().IsAssignableFrom(o.GetType().GetTypeInfo()) : |
||||
|
false; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,137 @@ |
|||||
|
// -----------------------------------------------------------------------
|
||||
|
// <copyright file="TreeDataTemplate`1.cs" company="Steven Kirk">
|
||||
|
// Copyright 2014 MIT Licence. See licence.md for more information.
|
||||
|
// </copyright>
|
||||
|
// -----------------------------------------------------------------------
|
||||
|
|
||||
|
namespace Perspex.Controls.Templates |
||||
|
{ |
||||
|
using System; |
||||
|
using System.Collections; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// A template used to build hierachical data.
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="T">The type of the template's data.</typeparam>
|
||||
|
public class TreeDataTemplate<T> : TreeDataTemplate |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the <see cref="TreeDataTemplate{T}"/> class.
|
||||
|
/// </summary>
|
||||
|
/// <param name="build">
|
||||
|
/// A function which when passed an object of <typeparamref name="T"/> returns a control.
|
||||
|
/// </param>
|
||||
|
/// <param name="itemsSelector">
|
||||
|
/// A function which when passed an object of <typeparamref name="T"/> returns the child
|
||||
|
/// items.
|
||||
|
/// </param>
|
||||
|
public TreeDataTemplate( |
||||
|
Func<T, Control> build, |
||||
|
Func<T, IEnumerable> itemsSelector) |
||||
|
: base( |
||||
|
typeof(T), |
||||
|
TreeDataTemplate<T>.Cast(build), |
||||
|
TreeDataTemplate<T>.Cast(itemsSelector)) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the <see cref="TreeDataTemplate{T}"/> class.
|
||||
|
/// </summary>
|
||||
|
/// <param name="build">
|
||||
|
/// A function which when passed an object of <typeparamref name="T"/> returns a control.
|
||||
|
/// </param>
|
||||
|
/// <param name="itemsSelector">
|
||||
|
/// A function which when passed an object of <typeparamref name="T"/> returns the child
|
||||
|
/// items.
|
||||
|
/// </param>
|
||||
|
/// <param name="isExpanded">
|
||||
|
/// A function which when passed an object of <typeparamref name="T"/> returns the the
|
||||
|
/// initial expanded state of the node.
|
||||
|
/// </param>
|
||||
|
public TreeDataTemplate( |
||||
|
Func<T, Control> build, |
||||
|
Func<T, IEnumerable> itemsSelector, |
||||
|
Func<T, bool> isExpanded) |
||||
|
: base( |
||||
|
typeof(T), |
||||
|
TreeDataTemplate<T>.Cast(build), |
||||
|
TreeDataTemplate<T>.Cast(itemsSelector), |
||||
|
TreeDataTemplate<T>.Cast(isExpanded)) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the <see cref="TreeDataTemplate{T}"/> class.
|
||||
|
/// </summary>
|
||||
|
/// <param name="match">
|
||||
|
/// A function which determines whether the data template matches the specified data.
|
||||
|
/// </param>
|
||||
|
/// <param name="build">
|
||||
|
/// A function which when passed a matching object returns a control.
|
||||
|
/// </param>
|
||||
|
/// <param name="itemsSelector">
|
||||
|
/// A function which when passed a matching object returns the child items.
|
||||
|
/// </param>
|
||||
|
public TreeDataTemplate( |
||||
|
Func<T, bool> match, |
||||
|
Func<T, Control> build, |
||||
|
Func<T, IEnumerable> itemsSelector) |
||||
|
: base( |
||||
|
TreeDataTemplate<T>.CastMatch(match), |
||||
|
TreeDataTemplate<T>.Cast(build), |
||||
|
TreeDataTemplate<T>.Cast(itemsSelector)) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the <see cref="TreeDataTemplate{T}"/> class.
|
||||
|
/// </summary>
|
||||
|
/// <param name="match">
|
||||
|
/// A function which determines whether the data template matches the specified data.
|
||||
|
/// </param>
|
||||
|
/// <param name="build">
|
||||
|
/// A function which when passed a matching object returns a control.
|
||||
|
/// </param>
|
||||
|
/// <param name="itemsSelector">
|
||||
|
/// A function which when passed a matching object returns the child items.
|
||||
|
/// </param>
|
||||
|
/// <param name="isExpanded">
|
||||
|
/// A function which when passed a matching object returns the the initial expanded state
|
||||
|
/// of the node.
|
||||
|
/// </param>
|
||||
|
public TreeDataTemplate( |
||||
|
Func<T, bool> match, |
||||
|
Func<T, Control> build, |
||||
|
Func<T, IEnumerable> itemsSelector, |
||||
|
Func<T, bool> isExpanded) |
||||
|
: base( |
||||
|
TreeDataTemplate<T>.CastMatch(match), |
||||
|
TreeDataTemplate<T>.Cast(build), |
||||
|
TreeDataTemplate<T>.Cast(itemsSelector), |
||||
|
TreeDataTemplate<T>.Cast(isExpanded)) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Casts a typed match function to an untyped match function.
|
||||
|
/// </summary>
|
||||
|
/// <param name="f">The typed function.</param>
|
||||
|
/// <returns>The untyped function.</returns>
|
||||
|
private static Func<object, bool> CastMatch(Func<T, bool> f) |
||||
|
{ |
||||
|
return o => (o is T) ? f((T)o) : false; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Casts a function with a typed parameter to an untyped function.
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="TResult">The result.</typeparam>
|
||||
|
/// <param name="f">The typed function.</param>
|
||||
|
/// <returns>The untyped function.</returns>
|
||||
|
private static Func<object, TResult> Cast<TResult>(Func<T, TResult> f) |
||||
|
{ |
||||
|
return o => f((T)o); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -1,138 +0,0 @@ |
|||||
// -----------------------------------------------------------------------
|
|
||||
// <copyright file="TreeDataTemplate.cs" company="Steven Kirk">
|
|
||||
// Copyright 2014 MIT Licence. See licence.md for more information.
|
|
||||
// </copyright>
|
|
||||
// -----------------------------------------------------------------------
|
|
||||
|
|
||||
namespace Perspex.Controls |
|
||||
{ |
|
||||
using System; |
|
||||
using System.Collections; |
|
||||
using System.Reflection; |
|
||||
using Perspex.Controls.Templates; |
|
||||
|
|
||||
public class TreeDataTemplate : DataTemplate |
|
||||
{ |
|
||||
public TreeDataTemplate( |
|
||||
Func<object, IControl> build, |
|
||||
Func<object, IEnumerable> itemsSelector) |
|
||||
: this(o => true, build, itemsSelector) |
|
||||
{ |
|
||||
} |
|
||||
|
|
||||
public TreeDataTemplate( |
|
||||
Type type, |
|
||||
Func<object, IControl> build, |
|
||||
Func<object, IEnumerable> itemsSelector) |
|
||||
: this(o => IsInstance(o, type), build, itemsSelector) |
|
||||
{ |
|
||||
} |
|
||||
|
|
||||
public TreeDataTemplate( |
|
||||
Type type, |
|
||||
Func<object, IControl> build, |
|
||||
Func<object, IEnumerable> itemsSelector, |
|
||||
Func<object, bool> isExpanded) |
|
||||
: this(o => IsInstance(o, type), build, itemsSelector, isExpanded) |
|
||||
{ |
|
||||
} |
|
||||
|
|
||||
public TreeDataTemplate( |
|
||||
Func<object, bool> match, |
|
||||
Func<object, IControl> build, |
|
||||
Func<object, IEnumerable> itemsSelector) |
|
||||
: this(match, build, itemsSelector, _ => false) |
|
||||
{ |
|
||||
this.ItemsSelector = itemsSelector; |
|
||||
} |
|
||||
|
|
||||
public TreeDataTemplate( |
|
||||
Func<object, bool> match, |
|
||||
Func<object, IControl> build, |
|
||||
Func<object, IEnumerable> itemsSelector, |
|
||||
Func<object, bool> isExpanded) |
|
||||
: base(match, build) |
|
||||
{ |
|
||||
this.ItemsSelector = itemsSelector; |
|
||||
this.IsExpanded = isExpanded; |
|
||||
} |
|
||||
|
|
||||
public Func<object, IEnumerable> ItemsSelector { get; private set; } |
|
||||
|
|
||||
public Func<object, bool> IsExpanded { get; private set; } |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Determines of an object is of the specified type.
|
|
||||
/// </summary>
|
|
||||
/// <param name="o">The object.</param>
|
|
||||
/// <param name="t">The type.</param>
|
|
||||
/// <returns>
|
|
||||
/// True if <paramref name="o"/> is of type <paramref name="t"/>, otherwise false.
|
|
||||
/// </returns>
|
|
||||
private static bool IsInstance(object o, Type t) |
|
||||
{ |
|
||||
return (o != null) ? |
|
||||
t.GetTypeInfo().IsAssignableFrom(o.GetType().GetTypeInfo()) : |
|
||||
false; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public class TreeDataTemplate<T> : TreeDataTemplate |
|
||||
{ |
|
||||
public TreeDataTemplate( |
|
||||
Func<T, Control> build, |
|
||||
Func<T, IEnumerable> itemsSelector) |
|
||||
: base( |
|
||||
typeof(T), |
|
||||
TreeDataTemplate<T>.Cast(build), |
|
||||
TreeDataTemplate<T>.Cast(itemsSelector)) |
|
||||
{ |
|
||||
} |
|
||||
|
|
||||
public TreeDataTemplate( |
|
||||
Func<T, Control> build, |
|
||||
Func<T, IEnumerable> itemsSelector, |
|
||||
Func<T, bool> isExpanded) |
|
||||
: base( |
|
||||
typeof(T), |
|
||||
TreeDataTemplate<T>.Cast(build), |
|
||||
TreeDataTemplate<T>.Cast(itemsSelector), |
|
||||
TreeDataTemplate<T>.Cast(isExpanded)) |
|
||||
{ |
|
||||
} |
|
||||
|
|
||||
public TreeDataTemplate( |
|
||||
Func<T, bool> match, |
|
||||
Func<T, Control> build, |
|
||||
Func<T, IEnumerable> itemsSelector) |
|
||||
: base( |
|
||||
TreeDataTemplate<T>.CastMatch(match), |
|
||||
TreeDataTemplate<T>.Cast(build), |
|
||||
TreeDataTemplate<T>.Cast(itemsSelector)) |
|
||||
{ |
|
||||
} |
|
||||
|
|
||||
public TreeDataTemplate( |
|
||||
Func<T, bool> match, |
|
||||
Func<T, Control> build, |
|
||||
Func<T, IEnumerable> itemsSelector, |
|
||||
Func<T, bool> isExpanded) |
|
||||
: base( |
|
||||
TreeDataTemplate<T>.CastMatch(match), |
|
||||
TreeDataTemplate<T>.Cast(build), |
|
||||
TreeDataTemplate<T>.Cast(itemsSelector), |
|
||||
TreeDataTemplate<T>.Cast(isExpanded)) |
|
||||
{ |
|
||||
} |
|
||||
|
|
||||
private static Func<object, bool> CastMatch(Func<T, bool> f) |
|
||||
{ |
|
||||
return o => (o is T) ? f((T)o) : false; |
|
||||
} |
|
||||
|
|
||||
private static Func<object, TResult> Cast<TResult>(Func<T, TResult> f) |
|
||||
{ |
|
||||
return o => f((T)o); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
Loading…
Reference in new issue