Delete selected parent node and child nodes - Collection was modified; enumeration operation may not execute [duplicate]
I have treeview control with one level of parent and child nodes, each node is having a checkbox for selecting nodes after selection if I click remove button I want to delete child or parent what ever is selected, Im using following code and it returns an error
Code
protected void btnRemoveOrganisation_Click(object sender, Ev开发者_如何学GoentArgs e)
{
foreach (TreeNode Item in tvwSelectedOrganisations.CheckedNodes)
{
if (Item.Parent == null)
{
foreach (TreeNode ChildNode in Item.ChildNodes)
{
Item.ChildNodes.Remove(ChildNode);
}
tvwSelectedOrganisations.Nodes.Remove(Item);
}
else
{
Item.Parent.ChildNodes.Remove(Item);
}
}
}
Error
Collection was modified; enumeration operation may not execute.
Modified code
protected void btnRemoveOrganisation_Click(object sender, EventArgs e)
{
TreeNodeCollection SelectedNodes = tvwSelectedOrganisations.CheckedNodes;
foreach (TreeNode Item in SelectedNodes)
{
if (Item.Parent == null)
{
tvwSelectedOrganisations.Nodes.Remove(Item);
}
else
{
tvwSelectedOrganisations.FindNode(Item.Parent.ValuePath).ChildNodes.Remove(Item);
}
if (SelectedNodes.Count == 0)
{
break;
}
}
}
Solution
int SelectedCount = SelectedNodes.Count;
for (int i = SelectedCount - 1; i >= 0; i--)
{
if (tvwSelectedOrganisations.CheckedNodes[i].Parent == null)
{
int j = tvwSelectedOrganisations.CheckedNodes[i].ChildNodes.Count;
tvwSelectedOrganisations.Nodes.Remove(tvwSelectedOrganisations.CheckedNodes[i]);
i += j;
}
else
{
tvwSelectedOrganisations.FindNode(tvwSelectedOrganisations.CheckedNodes[i].Parent.ValuePath).ShowCheckBox = false;
tvwSelectedOrganisations.FindNode(tvwSelectedOrganisations.CheckedNodes[i].Parent.ValuePath).ChildNodes.Remove(tvwSelectedOrganisations.CheckedNodes[i]);
}
}
Hope you are using .Net 3.5 or higher.
foreach (TreeNode ChildNode in Item.ChildNodes.ToList())
{
Item.ChildNodes.Remove(ChildNode);
}
EDIT
If Item.ChildNodes is not Enumerable. Try below then.
for( int i = Item.ChildNodes.Count - 1; i >= 0; i-- )
{
Item.ChildNodes.Remove(ChildNode);
}
Or
while (Item.ChildNodes.Count > 0)
{
Item.ChildNodes.Remove(ChildNode);
}
You can't have this line inside the foreach, because you're modifying the collection you're enumerating on:
tvwSelectedOrganisations.Nodes.Remove(Item);
Instead, build a new list of items to remove, then iterate through that list and remove the items outside of (and after) your existing foreach
.
Definitely, it will throw exception. You are not supposed to delete
or remove
an item in a collection by looping in the same collection. Instead copy the collection Item.ChildNodes
to an empty new Collection, try to loop in original collection and remove what items you want in the new collection, after looping outside the scope of loop again re-assign the modified collection to the original.
精彩评论