2011-09-13 52 views
6

我有一個父級和子級節點的樹視圖控件,每個節點都有一個複選框,用於在選擇後選擇節點,如果我單擊刪除按鈕我想要刪除孩子或家長所選擇的,我使用以下代碼,並返回一個錯誤刪除選定的父節點和子節點 - 集合已被修改;枚舉操作可能不會執行

代碼

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); 
      } 

     } 

    } 

錯誤

集合已修改;枚舉操作可能不會執行。

修改後的代碼

 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; 
       } 

      } 

     } 

解決方案

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

       } 

      } 
+0

發現解決方案,問題是由於通用列表正在使用,我已經用正確的代碼更新了帖子 – sudheshna

回答

4

希望你使用.net 3.5或更高版本。

foreach (TreeNode ChildNode in Item.ChildNodes.ToList()) 
{ 
    Item.ChildNodes.Remove(ChildNode); 
} 

編輯

如果Item.ChildNodes不Enumerable。然後嘗試下面。

for(int i = Item.ChildNodes.Count - 1; i >= 0; i--) 
{ 
    Item.ChildNodes.Remove(ChildNode); 
} 

或者

while (Item.ChildNodes.Count > 0) 
{ 
    Item.ChildNodes.Remove(ChildNode); 
} 
+0

,但是當我更改foreach循環時,它顯示構建錯誤「Error 'System.Web.UI.WebControls.TreeNodeCollection'不包含'ToList'的定義,並且沒有找到接受'System.Web.UI.WebControls.TreeNodeCollection'類型的第一個參數的擴展方法'ToList' (你是否缺少使用指令或程序集引用?)「 – sudheshna

+0

剛添加更多選項。 – CharithJ

+0

嗨Charith,我已經嘗試了for循環,它的工作原理,更新了正確的解決方案。謝謝 – sudheshna

2

你不能在foreach內這一行,因爲你改變你列舉的集合:

tvwSelectedOrganisations.Nodes.Remove(Item); 

取而代之的是,建立一個要刪除的項目的新列表,然後遍歷該列表並刪除現有的foreach之外(以及之後)的項目。

+0

SpikeX和Kalyan,我試過這個,我不是爲什麼它從我的新集合中刪除相同的項目,我也已修改我的帖子以包含我的新代碼。另外,如果我嘗試刪除單個節點或單個節點中的項目,它將起作用,但是如果在多個節點中選擇項目,它會使用框架4引發相同的異常 – sudheshna

1

肯定地說,它會拋出異常。您不應該通過在同一個集合中循環來在集合中將deleteremove中的項目組合起來。而是將集合Item.ChildNodes複製到一個空的新集合,嘗試在原始集合中循環,並在循環超出循環範圍之後,在新集合中刪除想要的項目,然後將修改後的集合重新分配給原始集合。

相關問題