首页 > 解决方案 > 如何遍历具有相同类型列表的对象列表并将每个对象添加到 TreeView?

问题描述

标题可能不是很清楚,但我会在这里尝试解释更多......

我有以下课程...

public class Node
{
    public string Name { get; set; } = string.Empty;

    public List<Node> Children { get; set; } = new List<Node>();

    public Node(string name, List<Node> children)
    {
        Name = name;
        Children = children;
    }

    public Node() {  }
}

我有一个TreeView应该像这样的元素......

- Root
    - Node 0_0
        - Node 1_0
            - Node 2_0
        - Node 1_1
    - Node 0_1
        - Node 1_0
        - Node 1_1

等等...

目前,我使用这种低效、糟糕、末日金字塔的方法......

var rootNode = GetNodeFromString();

var rootTreeNode = TreeView1.Items.Add(new TreeNode(rootNode.Name));

foreach (var child0 in rootNode.Children)
{       
    var node1 = rootTreeNode.Items.Add(new TreeNode(child0.Name));  

    foreach (var child1 in node1.Children)
    {
        node1.Items.Add(new TreeNode(child1.Name));

        // Repeat the code 30 more times...
    }
}

有没有其他方法可以实现无限深度?(不是真的无限,比如 128 层

标签: c#winformsloops

解决方案


通用解决方案

您可以像这样创建一个通用方法:

private TreeNode ConvertEntityToTreeNode<T>(
    T entity,
    Func<T, IEnumerable<T>> getChilds,
    Func<T, TreeNode> createTreeNode)
{
    TreeNode node = createTreeNode(entity);
    var childs = getChilds(entity);
    foreach (T child in childs)
        node.Nodes.Add(ConvertEntityToTreeNode(child, getChilds, createTreeNode));
    return node;
}
  • entity:将在树层次结构中成为根的实体。
  • getChilds:从节点获取子节点的表达式。
  • createTreeNodeTreeNode:从实体创建的表达式。

然后以这种方式使用它:

var treeNode = ConvertEntityToTreeNode(node, x => x.Children, x => new TreeNode(x.Name));
treeView1.Nodes.Add(treeNode);

非通用解决方案

你自己已经找到了。这非常简单明了:

private TreeNode ConvertEntityToTreeNode(Node entity)
{
    var node = new TreeNode(entity.Name);
    foreach (var child in entity.Children)
        node.Nodes.Add(ConvertEntityToTreeNode(child));
    return node;
}

然后以这种方式使用它:

var treeNode = ConvertEntityToTreeNode(node);
treeView1.Nodes.Add(treeNode);

为什么您可能需要通用解决方案?

以防万一您有几个节点类和树。创建的算法总是一样的,你只需要知道:

  1. 根对象
  2. 如何获得对象的孩子
  3. 如何TreeNode使用对象创建

然后该算法始终是您在通用方法中看到的递归算法。


推荐阅读