代码之家  ›  专栏  ›  技术社区  ›  James

如何有效地从树视图中删除选中的项?

  •  7
  • James  · 技术社区  · 17 年前

    如何轻松地遍历TreeView中的所有节点,检查它们的.checked属性,然后删除所有选中的节点?

    这看起来很简单,但是您不应该修改一个正在迭代的集合,从而消除了“foreach”循环的可能性。(nodes.remove调用正在修改集合。)如果尝试这样做,效果是只删除.checked节点的一半。

    即使其中一个使用两个过程:首先创建一个临时索引列表,然后在第二个过程中按索引删除——每次删除索引时,索引都会发生更改,从而使索引列表的完整性失效。

    那么,最有效的方法是什么呢?

    下面是一个看起来不错的代码示例,但实际上只删除了.checked节点的一半。

                foreach (TreeNode parent in treeView.Nodes)
                {
                    if (parent.Checked)
                    {
                        treeView.Nodes.Remove(parent);
                    }
                    else
                    {
                        foreach (TreeNode child in parent.Nodes)
                        {
                            if (child.Checked) parent.Nodes.Remove(child);
                        }
                    }
                }
    

    (是的,其目的只是从两层树中修剪节点。)

    4 回复  |  直到 17 年前
        1
  •  6
  •   Jon B    17 年前

    这将在枚举节点之后删除它们,并且可以递归地用于n层节点。

    void RemoveCheckedNodes(TreeNodeCollection nodes)
    {
        List<TreeNode> checkedNodes = new List<TreeNode>();
    
        foreach (TreeNode node in nodes)
        {
            if (node.Checked)
            {
                checkedNodes.Add(node);
            }
            else
            {
                RemoveCheckedNodes(nodes.ChildNodes);
            }
        }
    
        foreach (TreeNode checkedNode in checkedNodes)
        {
            nodes.Remove(checkedNode);
        }
    }
    
        2
  •  7
  •   Jay Mooney    17 年前

    尝试向后遍历节点。这样索引就不会超过节点大小:

    for( int ndx = nodes.Count; ndx > 0; ndx--)
    {
      TreeNode node = nodes[ndx-1];
      if (node.Checked)
      {
         nodes.Remove(node);
      }
       // Recurse through the child nodes...
    }
    
        3
  •  3
  •   Chris Brandsma    17 年前

    如果您想有效地执行此操作,则需要在检查节点时跟踪它们。将选中的树节点存储在列表中(取消选中时将其删除)。

    如果您有一个唯一的键和许多节点来跟踪,那么也可以考虑使用字典。但如果你只处理10-50的问题,可能不会有很大的不同。

    然后,您不需要遍历整个树,而只需遍历(较小的)节点列表。

        4
  •  1
  •   Steven Evers    17 年前

    在迭代的同时,您可以构建一个未选中项的新列表,然后将TreeView重新绑定到该新列表(放弃旧列表)。