递归填充树视图(复杂的情况)

时间:2009-12-08 21:31:34

标签: c# asp.net treeview

我在递归填充树视图方面遇到了一些严重的问题,我会给予任何帮助。

我有这个DataTable:

ItemID ItemDesc  Project  Room  Closet  

Item1  Item1Desc Project1 RoomE Closet-7  
Item2  Item2Desc Project1 RoomW Closet8  
Item3  Item3Desc Project1 RoomW Closet8  
Item4  Item4Desc Project1 RoomN Closet2  
Item5  Item5Desc Project1 RoomN Closet9  
Item6  Item6Desc Project2 RoomN Closet2  
Item7  Item7Desc Project2 RoomW Closet9  

我想创建一个这样的TreeView:

  • PROJECT1
    • Roome来
      • Closet7
        • Item1Desc
    • RoomW
      • Closet8
        • Item2Desc
        • Item3Desc
    • RoomN
      • Closet2
        • Item4Desc
      • Closet9
        • Item5Desc
  • Project2的
    • RoomN
      • Closet2
        • Item6Desc
    • RoomW
      • Closet2
        • Item7Desc

我尝试数据树视图的方式是使用

private List<treeDataItem> treeData = new List<treeDataItem>();  
mytreeView.DataFieldID = "ID";  
mytreeView.DataFieldParentID = "ParentID";  
mytreeView.DataTextField = "Text";  
mytreeView.DataValueField = "Value";  
mytreeView.DataSource = treeData;  
mytreeView.DataBind();  

我正在尝试通过DataTable循环,因此我可以填充treeData但我无法正确输入ParentID。

另外,为了使事情复杂化,DataTable中的字段数量是可变的 这意味着我可以有更多字段来识别像“壁橱抽屉”这样的项目,然后可能是“壁橱抽屉部分”等。

所以DataTable可以像:

ItemID     ItemDescription     Project     Room     Closet     Closet Drawer  

又一次:

ItemID     ItemDescription     Project     Room     Closet     Closet Drawer     Closet Drawer Section

基于用户选择。

这是treeDataItem类:

internal class treeDataItem
{
    public string Text { get; set; }
    public int ID { get; set; }
    public int ParentID { get; set; }
    public Guid Value { get; set; }

    public treeDataItem(int id, int parentId, string text, string value)
    {
        ID = id;
        ParentID = parentId;
        Text = text;
        Value = value;
    }
}

3 个答案:

答案 0 :(得分:6)

我不熟悉ASP.NET树视图控件,所以这是一个通用解决方案。

DateTable行

class Foo
{
    public string A { get; set; }
    public string B { get; set; }
    public string C { get; set; }
}

树节点

class Node
{
    private readonly string name;
    private readonly Node[] children;

    public Node(string name, Node[] children)
    {
        this.name = name;
        this.children = children;
    }
}

将行分组到节点的递归算法

static IEnumerable<Node> Traverse<T, U>(
    IEnumerable<T> items,
    Func<T, U>[] keySelectors,
    int selectorIndex)
{
    if (selectorIndex < keySelectors.Length)
    {
        foreach (var g in items.GroupBy(keySelectors[selectorIndex]))
        {
            yield return new Node(g.Key.ToString(),
                Traverse(g, keySelectors, selectorIndex + 1).ToArray());
        }
    }
}

<强>测试

var items = new[]
               {
                   new Foo { A = "A1", B = "B1", C = "C1" },
                   new Foo { A = "A1", B = "B1", C = "C2" },
                   new Foo { A = "A1", B = "B2", C = "C1" },
                   new Foo { A = "A1", B = "B2", C = "C2" },
                   new Foo { A = "A2", B = "B1", C = "C1" },
                   new Foo { A = "A2", B = "B1", C = "C2" },
                   new Foo { A = "A2", B = "B2", C = "C1" },
                   new Foo { A = "A2", B = "B2", C = "C2" },
               };

var nodes = Traverse(items, new Func<Foo, string>[]
                            {
                                f => f.A,
                                f => f.B,
                                f => f.C
                            }, 0).ToArray();

<强>输出

  • A1
    • B1
      • C1
      • C2
    • B2
      • C1
      • C2
  • A2
    • B1
      • C1
      • C2
    • B2
      • C1
      • C2

答案 1 :(得分:0)

我没有C#的专业知识,但我会在两个阶段处理这样的问题:

  1. 将输入解析为可用的内容。
  2. 然后将树视图绑定到它。
  3. 您的输入数据相当复杂,因此处理所有特殊情况的自定义解析器是合理的。

答案 2 :(得分:0)

            string[] data = new string[] {
            "Item1 Item1Desc Project1 RoomE Closet-7",
            "Item2 Item2Desc Project1 RoomW Closet8",
            "Item3 Item3Desc Project1 RoomW Closet8",
            "Item4 Item4Desc Project1 RoomN Closet2",
            "Item5 Item5Desc Project1 RoomN Closet9",
            "Item6 Item6Desc Project2 RoomN Closet2",
            "Item7 Item7Desc Project2 RoomW Closet9" };

        foreach (string row in data)
        {
            string[] columns = row.Split(' ');

            TreeNodeCollection treeNodes=treeView1.Nodes;

            for (int col = 2; col < columns.Length; col++)
            {
                string column = columns[col];
                if (!treeNodes.ContainsKey(column))
                {
                    treeNodes.Add(column, column);
                }
                TreeNode tn = treeNodes[column];
                treeNodes = tn.Nodes;
            }
            treeNodes.Add(string.Format("{0} - {1}", columns[0], columns[1]));
        }