3

首先,我们有万能的代码!

List nodes = new List();
TreeNode Temp = new TreeNode();

TreeNodeCollection nodeList = treeViewTab4DirectoryTree.Nodes;

while (nodeList.Count != 0)
{
    Temp = nodeList[0];

    while (Temp.FirstNode != null)
    {
        Temp = Temp.FirstNode;
    }

    if (!nodes.Contains(Temp.FullPath))
    {
        nodes.Add(Temp.Text);
    }

    nodeList.Remove(Temp);
}

现在的问题是:我编写了上面的代码,目的是创建一个包含树中所有节点的文本的列表。这完美无缺。我遇到的问题是,当我从变量中删除节点时,它们也会从实际列表中删除。问题是如何制作节点列表的副本,这样我就可以在不弄乱 ACTUAL 列表的情况下使用它们。我如何在不引用它的情况下复制它?任何帮助将不胜感激!

4

2 回答 2

3

出现您的问题是因为“nodeList”是对 treeViewTab4DirectoryTree.Nodes 的引用,而不是它的副本。

解决方案完全取决于您使用的 TreeNodeCollection 类型(WinForms、ASP.net 还是其他?),因为您需要寻找 .Copy()、.Clone()、.ToArray() 方法或类似地获取集合内容的副本,而不是对现有集合的引用。

例如,如果您使用 asp.net 并因此使用System.Web.UI.WebControls.TreeNodeCollection,则可以以类似于以下方式使用 .CopyTo 方法:

TreeNode[] x = null;
treeViewTab4DirectoryTree.Nodes.CopyTo(x, 0);
于 2010-02-24T13:50:47.330 回答
2

更新以显示基于堆栈的方法:

List<String> result = new List<String>();
Stack<IEnumerator> nodeColls = new Stack<IEnumerator>();
IEnumerator nodes = treeViewTab4DirectoryTree.Nodes.GetEnumerator();

nodeColls.Push(null);

while (nodes != null)
{
    while (nodes.MoveNext())
    {
        result.add(nodes.Current.FullPath);
        if (nodes.Current.FirstNode != null)
        {
            nodeColls.Push(nodes);
            nodes = nodes.Current.Nodes.GetEnumerator();
        }
    }

    nodes = nodeColls.Pop();
}

下面的代码不像注释中提到的那样工作,因为它没有遍历整个树,而只取每个顶级分支的第一个叶子节点。

我实际上认为原始代码(在问题中)也是这样做的,因为我认为 Remove 实际上会在找到它下的第一个叶节点后删除顶层节点;但相反,它会尝试从顶级节点集合中删除叶节点,如果找不到它就忽略它。

原始帖子,无效代码

首先,为什么需要从列表中删除项目?

List<string> nodes = new List<string>();

foreach (TreeNode tn in treeViewTab4DirectoryTree.Nodes)
{
    TreeNode temp = tn;

    while (Temp.FirstNode != null)
    {
        Temp = Temp.FirstNode;
    }

    if (!nodes.Contains(Temp.FullPath))
    {
        nodes.Add(Temp.Text);
    }
}

要回答您的具体问题,假设 Nodes 集合实现 IEnumerable,请使用:

List<TreeNode> nodeList = new List<TreeNode>(treeViewTab4DirectoryTree.Nodes);

如果您决定坚持使用 while 循环,则可以通过更改来保存实例化

TreeNode Temp = new TreeNode();

TreeNode Temp = null;

...您从未真正使用过您创建的对象,至少在您显示的部分代码中。

于 2010-02-24T14:01:39.777 回答