TreeNodeCollection引用问题

发布于 2024-08-22 13:21:37 字数 556 浏览 3 评论 0原文

首先我们有万能的代码!

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);
}

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

First off we have the almighty code!

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);
}

Now the problem: I have written the code above with the intent of creating a List containing the text from all the nodes in the tree. That works perfectly. The problem I am having is when I remove the nodes from my variable they are also being removed from the actual list. The question would be how can I make a copy of the list of nodes so I can play with them without messing with the ACTUAL list. How do I make a copy of it without just making a reference to it? Any help will be greatly appreciated!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

_蜘蛛 2024-08-29 13:21:37

出现您的问题是因为“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);

Your problem arises because "nodeList" is a reference to treeViewTab4DirectoryTree.Nodes, rather than a copy of it.

The solution depends entirely on the what type of TreeNodeCollection you're using (WinForms, ASP.net, something else?), as you'll need to look for a .Copy(), .Clone(), .ToArray() method or similar to take a copy of the contents of the collection, rather than a reference to the existing collection.

If, for example, you're using asp.net and thus the System.Web.UI.WebControls.TreeNodeCollection, you could use the .CopyTo method in a way similar to this:

TreeNode[] x = null;
treeViewTab4DirectoryTree.Nodes.CopyTo(x, 0);
踏雪无痕 2024-08-29 13:21:37

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

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();
}

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

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

原始帖子,不起作用的代码

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

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;

... 来保存实例化,至少您从未真正使用过您创建的对象在您展示的代码部分中。

Updated to show stack based approach:

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();
}

The code below does not work as was mentioned in comments, because it doesn't traverse the entire tree, but only takes the first leaf node of each top-level branch.

I actually thought the original code (in the question) did so too, because I thought the Remove would actually remove the top-level node after finding the first leaf node under it; but instead, it tries to remove the leaf node from the collection of top-level nodes, and just ignores it if it can't find it.

Original post, non-functioning code

First of all, why do you need to remove the items from your list?

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);
    }
}

To answer your concrete question, assuming the Nodes collection implements IEnumerable, use:

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

If you do decide to stick with your while loop, you can save an instatiation by changing

TreeNode Temp = new TreeNode();

to

TreeNode Temp = null;

... you're never actually using the object you create, at least in the part of the code you've shown.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文