将线性列表绑定<MyItem>到分层树视图


class MyItem
{
    public long ID;
    public string Name;
    public long? ParentID;
    public MyItem(long id, string name, long? parent)
    {
        ID = id;
        Name = name;
        ParentID= parent;
    }
}
List<MyItem> myItemList = new List<MyItem>();
myItemList.Add(new MyItem(1, "Item1", null));
myItemList.Add(new MyItem(2, "Item1", 1));
myItemList.Add(new MyItem(3, "Item1", 1));
myItemList.Add(new MyItem(4, "Item1", 5));
myItemList.Add(new MyItem(5, "Item1", null));
myItemList.Add(new MyItem(6, "Item1", 3));
myItemList.Add(new MyItem(7, "Item1", null));

我想用XAML将myItemList绑定到WPF树视图,以获得这样的视图。

1
  |--2
  |--3
     |--6
5
  |--4
7

我是这样解决的。我需要有两个类:

1) LinqToObjectsExtensionMethods:

using System;
using System.Collections.Generic;
using System.Linq;
namespace APTClient.Model
{
    static class LinqToObjectsExtensionMethods
    {
        private static IEnumerable<HierarchyNode<TEntity>> CreateHierarchy<TEntity, TProperty>(IEnumerable<TEntity> allItems, TEntity parentItem, Func<TEntity, TProperty> idProperty,
                                                                                           Func<TEntity, TProperty> parentIdProperty, object rootItemId, int maxDepth, int depth)
                                                                                          where TEntity : class
    {
        IEnumerable<TEntity> childs;
        if (rootItemId != null)
        {
            childs = allItems.Where(i => idProperty(i).Equals(rootItemId));
        }
        else
        {
            if (parentItem == null)
            {
                childs = allItems.Where(i => parentIdProperty(i).Equals(default(TProperty)));
            }
            else
            {
                childs = allItems.Where(i => parentIdProperty(i).Equals(idProperty(parentItem)));
            }
        }
        if (childs.Count() > 0)
        {
            depth++;
            if ((depth <= maxDepth) || (maxDepth == 0))
            {
                foreach (var item in childs)
                    yield return
                    new HierarchyNode<TEntity>()
                    {
                        Entity = item,
                        ChildNodes =
                        CreateHierarchy(allItems.AsEnumerable(), item, idProperty, parentIdProperty, null, maxDepth, depth),
                        Depth = depth,
                        Parent = parentItem
                    };
            }
        }
    }
    /// <summary>
    /// LINQ to Objects (IEnumerable) AsHierachy() extension method
    /// </summary>
    /// <typeparam name="TEntity">Entity class</typeparam>
    /// <typeparam name="TProperty">Property of entity class</typeparam>
    /// <param name="allItems">Flat collection of entities</param>
    /// <param name="idProperty">Func delegete to Id/Key of entity</param>
    /// <param name="parentIdProperty">Func delegete to parent Id/Key</param>
    /// <returns>Hierarchical structure of entities</returns>
    public static IEnumerable<HierarchyNode<TEntity>> AsHierarchy<TEntity, TProperty>(this IEnumerable<TEntity> allItems, Func<TEntity, TProperty> idProperty
                                                                                    , Func<TEntity, TProperty> parentIdProperty) where TEntity : class
    {
        return CreateHierarchy(allItems, default(TEntity), idProperty, parentIdProperty, null, 0, 0);
    }
    /// <summary>
    /// LINQ to Objects (IEnumerable) AsHierachy() extension method
    /// </summary>
    /// <typeparam name="TEntity">Entity class</typeparam>
    /// <typeparam name="TProperty">Property of entity class</typeparam>
    /// <param name="allItems">Flat collection of entities</param>
    /// <param name="idProperty">Func delegete to Id/Key of entity</param>
    /// <param name="parentIdProperty">Func delegete to parent Id/Key</param>
    /// <param name="rootItemId">Value of root item Id/Key</param>
    /// <returns>Hierarchical structure of entities</returns>
    public static IEnumerable<HierarchyNode<TEntity>> AsHierarchy<TEntity, TProperty>(this IEnumerable<TEntity> allItems, Func<TEntity, TProperty> idProperty
                                                                                    , Func<TEntity, TProperty> parentIdProperty, object rootItemId) where TEntity : class
    {
        return CreateHierarchy(allItems, default(TEntity), idProperty, parentIdProperty, rootItemId, 0, 0);
    }
    /// <summary>
    /// LINQ to Objects (IEnumerable) AsHierachy() extension method
    /// </summary>
    /// <typeparam name="TEntity">Entity class</typeparam>
    /// <typeparam name="TProperty">Property of entity class</typeparam>
    /// <param name="allItems">Flat collection of entities</param>
    /// <param name="idProperty">Func delegete to Id/Key of entity</param>
    /// <param name="parentIdProperty">Func delegete to parent Id/Key</param>
    /// <param name="rootItemId">Value of root item Id/Key</param>
    /// <param name="maxDepth">Maximum depth of tree</param>
    /// <returns>Hierarchical structure of entities</returns>
    public static IEnumerable<HierarchyNode<TEntity>> AsHierarchy<TEntity, TProperty>(this IEnumerable<TEntity> allItems, Func<TEntity, TProperty> idProperty
                                                                                    , Func<TEntity, TProperty> parentIdProperty, object rootItemId, int maxDepth) where TEntity : class
    {
        return CreateHierarchy(allItems, default(TEntity), idProperty, parentIdProperty, rootItemId, maxDepth, 0);
    }
}}

2) HierarchyNode<T>:

using System.Collections.Generic;
namespace APTClient.Model
{
    public class HierarchyNode<T> where T : class
    {
        public T Entity { get; set; }
        public IEnumerable<HierarchyNode<T>> ChildNodes { get; set; }
        public int Depth { get; set; }
        public T Parent { get; set; }
    }
}

我有List<MyItem> myItemList;

List<MyItem> myItemList = new List<MyItem>(); 
myItemList.Add(new MyItem(1, "Item1", null)); 
myItemList.Add(new MyItem(2, "Item1", 1)); 
myItemList.Add(new MyItem(3, "Item1", 1)); 
myItemList.Add(new MyItem(4, "Item1", 5)); 
myItemList.Add(new MyItem(5, "Item1", null)); 
myItemList.Add(new MyItem(6, "Item1", 3)); 
myItemList.Add(new MyItem(7, "Item1", null)); 
然后

List<HierarchyNode<MyItem>> = myItemList.AsHierarchy(m => m.ID, m => m.ParentID);

最新更新