Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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, EventArgs 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]);

                }

            }
like image 939
sudheshna Avatar asked Sep 13 '11 12:09

sudheshna


2 Answers

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);
}
like image 150
CharithJ Avatar answered Oct 27 '22 03:10

CharithJ


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.

like image 2
qJake Avatar answered Oct 27 '22 02:10

qJake