首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >递归树创建

问递归树创建
EN

Stack Overflow用户
提问于 2012-07-06 23:00:03
回答 4查看 14.6K关注 0票数 5

我在C#中有一个具有以下属性的Node类:

代码语言:javascript
复制
public class Node
{
   public int Id {get;set;}
   public int? ParentId {get;set;}
   public string Label {get;set;}
}

我有一个TreeView控件,它提供了以下方法来创建新节点:

代码语言:javascript
复制
MyTreeView.CreateNode(key, label);
parent.Nodes.CreateNode(key, label);

如果我想添加一个新的子节点,我需要使用第二种方法,否则使用第一种方法。两者都返回TreeNode类型的对象。

考虑到根节点具有ParentId = null,如何在C#中创建一个递归函数来填充树视图

这就是我到目前为止所做的:

代码语言:javascript
复制
// create a list of root nodes
var roots = myList.Where(x => x.ParentId == null);
// send the roots to a recursive func
foreach(var root in roots)
{
   AddNode(null,root,myList);
}

这是我的递归函数:

代码语言:javascript
复制
private void AddNode(Node parent, Node current, IList<Node> items)
{
   TreeNode treenode = null;
   if(parent == null)
   {
      treenode = mytree.CreateNode(current.Id.ToString(), current.Label);
   }else{
      var parentnode = mytree.GetNode(parent.Id.ToString());
      treenode = parentnode.Nodes.CreateNode(current.Id.ToString(), current.Label);
   }
   // call the recursion for the children
   var children = items.Where(x => x.ParentId == current.Id);
   foreach(var child in children)
   {
      AddNode(current, child, items);
   }
}
EN

回答 4

Stack Overflow用户

发布于 2012-07-25 01:14:29

如果树视图控件是从System.Windows.Forms.TreeView派生的,则可以替换

代码语言:javascript
复制
MyTreeView.CreateNode(key, label);
parent.Nodes.CreateNode(key, label);

使用

代码语言:javascript
复制
MyTreeView.Nodes.Add(key, label);
parent.Nodes.Add(key, label);

因此,调用总是转到类型为TreeNodeCollection的节点集合。现在可以使用Nodes集合作为参数,而不是Node对象。

代码语言:javascript
复制
var roots = myList.Where(x => x.ParentId == null);
foreach (var root in roots)
{
    AddNode(mytree.Nodes, root, myList);
}

private void AddNode(TreeNodeCollection nodes, Node current, IList<Node> items)
{
    TreeNode treenode = nodes.Add(current.Id.ToString(), current.Label);

    var children = items.Where(x => x.ParentId == current.Id);
    foreach (var child in children)
    {
        AddNode(treenode.Nodes, child, items);
    }
}

这有两个好处:

  1. 你不需要每次都查找父级,
  2. 你只有一次调用

但是,如果您无法访问每个根的AddNode调用中的TreeView.Nodes集合,则必须在AddNode方法的顶部进行检查。

代码语言:javascript
复制
var roots = myList.Where(x => x.ParentId == null);
foreach (var root in roots)
{
    AddNode(null, root, myList);
}

private void AddNode(TreeNodeCollection nodes, Node current, IList<Node> items)
{
    if (nodes == null)
    {
        nodes = myTree.Nodes;
    }

    ...
}
票数 2
EN

Stack Overflow用户

发布于 2012-10-07 20:29:34

尝试以下代码:

代码语言:javascript
复制
var lookup = myList.ToLookup(n => n.ParentId.ToString());

Action<IEnumerable<TreeNode>> addChildren = null;
addChildren = tns =>
{
    var query =
        from tn in tns
        from cn in lookup[tn.Name]
        select tn.Nodes.CreateNode(cn.Id.ToString(), cn.Label);
    var nodes = query.ToArray();
    if (nodes.Length > 0)
    {
        addChildren(nodes);
    }
};

addChildren(
    lookup[null]
        .Select(n =>
            MyTreeView.CreateNode(n.Id.ToString(), n.Label)));

我无法完全测试它,因此您可能需要更改一些代码才能使其工作,但它应该相当接近。

票数 0
EN

Stack Overflow用户

发布于 2015-10-23 13:06:33

我可能会做这样的事...

代码语言:javascript
复制
public class Node
{
    public int Id { get; set; }
    public int? ParentId { get; set; }
    public string Label { get; set; }

    public Node(int? parentId, int id, string label)
    {
        ParentId = parentId;
        Id = id;
        Label = label;
    }
}

public class TreeNode : List<TreeNode>
{
    public string Key { get; set; }
    public string Label { get; set; }


    public IEnumerable<TreeNode> Descendants
    {
        get
        {
            yield return this;

            foreach (var child in this)
            {
                foreach (var descendant in child.Descendants)
                {
                    yield return descendant;
                }

            }
        }
    }

    public TreeNode(string key, string label)
    {
        Key = key;
        Label = label;
    }

    public void CreateNode(int id, string label)
    {
        Add(new TreeNode(id.ToString(), label));
    }
}

public class Tree
{
    private TreeNode _root = new TreeNode(null, null);

    public Tree(IEnumerable<Node> nodes)
    {
        nodes.ToList().ForEach(node => CreateNode(node.ParentId, node.Id, node.Label));
    }

    public void CreateNode(int? parentId, int id, string label)
    {
        if (parentId == null)
        {
            _root.CreateNode(id, label);
        }
        else
        {
            _root.Descendants.First(x => x.Key == parentId.ToString()).CreateNode(id, label);
        }
    }

    public IEnumerable<TreeNode> Descendants => _root.Descendants;
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11364719

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档