我在C#中有一个具有以下属性的Node类:
public class Node
{
public int Id {get;set;}
public int? ParentId {get;set;}
public string Label {get;set;}
}我有一个TreeView控件,它提供了以下方法来创建新节点:
MyTreeView.CreateNode(key, label);
parent.Nodes.CreateNode(key, label);如果我想添加一个新的子节点,我需要使用第二种方法,否则使用第一种方法。两者都返回TreeNode类型的对象。
考虑到根节点具有ParentId = null,如何在C#中创建一个递归函数来填充树视图
这就是我到目前为止所做的:
// 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);
}这是我的递归函数:
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);
}
}发布于 2012-07-25 01:14:29
如果树视图控件是从System.Windows.Forms.TreeView派生的,则可以替换
MyTreeView.CreateNode(key, label);
parent.Nodes.CreateNode(key, label);使用
MyTreeView.Nodes.Add(key, label);
parent.Nodes.Add(key, label);因此,调用总是转到类型为TreeNodeCollection的节点集合。现在可以使用Nodes集合作为参数,而不是Node对象。
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);
}
}这有两个好处:
但是,如果您无法访问每个根的AddNode调用中的TreeView.Nodes集合,则必须在AddNode方法的顶部进行检查。
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;
}
...
}发布于 2012-10-07 20:29:34
尝试以下代码:
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)));我无法完全测试它,因此您可能需要更改一些代码才能使其工作,但它应该相当接近。
发布于 2015-10-23 13:06:33
我可能会做这样的事...
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;
}https://stackoverflow.com/questions/11364719
复制相似问题