开发者

Delete selected parent node and child nodes - Collection was modified; enumeration operation may not execute [duplicate]

开发者 https://www.devze.com 2023-04-05 01:33 出处:网络
This question already has answers here: How do I loop through items in a list box and then remove those item?
This question already has answers here: How do I loop through items in a list box and then remove those item? (8 answers) Closed 9 years ago.

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.

0

精彩评论

暂无评论...
验证码 换一张
取 消