如何在树视图中修复 foreach
How to fix foreach in treeview
我正在通过本教程执行我的树视图删除按钮事件:
Youtube tutorial
我做了所有与教程中所示相同的事情:
private void button2_Click(object sender, EventArgs e)
{
RemoveCheckedNodes(treeView1.Nodes);
}
List<TreeNode> checkedNodes = new List<TreeNode>();
void RemoveCheckedNodes(TreeNodeCollection nodes)
{
foreach (TreeNode node in nodes )
{
if (node.Checked)
{
checkedNodes.Add(node);
}
else
{
RemoveCheckedNodes(node.Nodes);
}
foreach (TreeNode checkedNode in checkedNodes)
{
nodes.Remove(checkedNode);
}
}
}
但是它在 foreach 中抛出错误:'System.NullReferenceException' 类型的未处理异常发生在 project_TreeView.exe
同样很奇怪的是,一切都适用于最后一个节点。所以我猜我的 foreach 不工作。有什么想法吗?
EDIT:
So I found this is working, If I am removing last and before last node. How to make it, that I could remove any node(For example first and last)
谢谢。
如果我是对的,foreach 循环是只读迭代,我认为您应该使用 for 循环从集合中删除对象。
第二个 foreach 应该在第一个之外。
private void button2_Click(object sender, EventArgs e)
{
RemoveCheckedNodes(treeView1.Nodes);
}
List<TreeNode> checkedNodes = new List<TreeNode>();
void RemoveCheckedNodes(TreeNodeCollection nodes)
{
foreach (TreeNode node in nodes )
{
if (node.Checked)
{
checkedNodes.Add(node);
}
else
{
RemoveCheckedNodes(node.Nodes);
}
}
foreach (TreeNode checkedNode in checkedNodes)
{
nodes.Remove(checkedNode);
}
}
我会将已检查节点的搜索移动到一个单独的方法中。所以你先找到所有节点,然后删除它们。
目前您的代码会多次尝试删除相同的节点(在 RemoveCheckedNodes 的每次递归调用中,即使您将循环移出另一个循环,删除仍会被多次调用。
我还会为 checkedNodes 列表使用局部变量。您的列表未清除,因此它将包含已删除的项目。
如果您的问题是查找或删除节点,这种方式更易于调试:
private void button2_Click(object sender, EventArgs e)
{
RemoveChecked(treeView1.Nodes);
}
void RemoveChecked(TreeNodeCollection nodes)
{
foreach (TreeNode checkedNode in FindCheckedNodes(nodes))
{
nodes.Remove(checkedNode);
}
}
private List<TreeNode> FindCheckedNodes(TreeNodeCollection nodes)
{
List<TreeNode> checkedNodes = new List<TreeNode>()
foreach (TreeNode node in nodes)
{
if (node.Checked)
{
checkedNodes.Add(node);
}
else
{
// find checked childs
checkedNodes.AddRange(FindCheckedNodes(node.Nodes));
}
}
return checkedNodes;
}
我正在通过本教程执行我的树视图删除按钮事件: Youtube tutorial
我做了所有与教程中所示相同的事情:
private void button2_Click(object sender, EventArgs e)
{
RemoveCheckedNodes(treeView1.Nodes);
}
List<TreeNode> checkedNodes = new List<TreeNode>();
void RemoveCheckedNodes(TreeNodeCollection nodes)
{
foreach (TreeNode node in nodes )
{
if (node.Checked)
{
checkedNodes.Add(node);
}
else
{
RemoveCheckedNodes(node.Nodes);
}
foreach (TreeNode checkedNode in checkedNodes)
{
nodes.Remove(checkedNode);
}
}
}
但是它在 foreach 中抛出错误:'System.NullReferenceException' 类型的未处理异常发生在 project_TreeView.exe
同样很奇怪的是,一切都适用于最后一个节点。所以我猜我的 foreach 不工作。有什么想法吗?
EDIT: So I found this is working, If I am removing last and before last node. How to make it, that I could remove any node(For example first and last)
谢谢。
如果我是对的,foreach 循环是只读迭代,我认为您应该使用 for 循环从集合中删除对象。
第二个 foreach 应该在第一个之外。
private void button2_Click(object sender, EventArgs e)
{
RemoveCheckedNodes(treeView1.Nodes);
}
List<TreeNode> checkedNodes = new List<TreeNode>();
void RemoveCheckedNodes(TreeNodeCollection nodes)
{
foreach (TreeNode node in nodes )
{
if (node.Checked)
{
checkedNodes.Add(node);
}
else
{
RemoveCheckedNodes(node.Nodes);
}
}
foreach (TreeNode checkedNode in checkedNodes)
{
nodes.Remove(checkedNode);
}
}
我会将已检查节点的搜索移动到一个单独的方法中。所以你先找到所有节点,然后删除它们。
目前您的代码会多次尝试删除相同的节点(在 RemoveCheckedNodes 的每次递归调用中,即使您将循环移出另一个循环,删除仍会被多次调用。
我还会为 checkedNodes 列表使用局部变量。您的列表未清除,因此它将包含已删除的项目。
如果您的问题是查找或删除节点,这种方式更易于调试:
private void button2_Click(object sender, EventArgs e)
{
RemoveChecked(treeView1.Nodes);
}
void RemoveChecked(TreeNodeCollection nodes)
{
foreach (TreeNode checkedNode in FindCheckedNodes(nodes))
{
nodes.Remove(checkedNode);
}
}
private List<TreeNode> FindCheckedNodes(TreeNodeCollection nodes)
{
List<TreeNode> checkedNodes = new List<TreeNode>()
foreach (TreeNode node in nodes)
{
if (node.Checked)
{
checkedNodes.Add(node);
}
else
{
// find checked childs
checkedNodes.AddRange(FindCheckedNodes(node.Nodes));
}
}
return checkedNodes;
}