2011-09-13 13 views
6

私は親ノードと子ノードの1つのレベルでツリービューコントロールを持っています。各ノードには、削除ボタンをクリックすると選択後のノードを選択するチェックボックスがあります。次のコードと、エラー選択した親ノードと子ノードを削除 - コレクションが変更されました。列挙操作が実行されない可能性があります

コード

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

     } 

    } 

コレクションが変更されたエラーを返します。列挙操作が実行されないことがあります。

変更されたコードあなたはあなたが列挙しているコレクションを修正しているので、あなたは、foreachの内部にこの行を持つことができません

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

EDIT

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

私はフレームワーク4を使用していますが、foreachループを変更したとき、 'System.Web.UI.WebControls.TreeNodeCollection'に 'ToList'の定義がなく、 'System.Web.UI.WebControls.TreeNodeCollection'タイプの最初の引数を受け入れる拡張メソッド 'ToList'が見つかりませんでした(usingディレクティブまたはアセンブリ参照がありませんか?) " – sudheshna

+0

追加オプションを追加しました。 – CharithJ

+0

こんにちはCharith、私はforループを試して、それは正常な解決策を使って投稿を更新しました。ありがとう – sudheshna

2

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

      } 

     } 

ソリューション:

tvwSelectedOrganisations.Nodes.Remove(Item); 

代わりに、削除するアイテムの新しいリストを作成し、そのリストを反復して、既存のforeachの外(および後)のアイテムを削除します。

+0

SpikeXとKalyan、私はこれを試しました。私は新しいコレクションから同じアイテムを削除しません。新しいコードを含めるように私の投稿を修正しました。また、単一のノードまたは単一のノード内のアイテムを削除しようとすると動作しますが、複数のノードで項目を選択すると同じ例外が発生します – sudheshna

1

確かに、それは例外がスローされます。 deleteまたはremoveには、コレクション内のアイテムを同じコレクションでループすることは想定されていません。代わりに、コレクションItem.ChildNodesを空の新しいコレクションにコピーし、元のコレクションをループし、新しいコレクションで必要なアイテムを削除してください。ループの範囲外にループした後、元のコレクションに再度割り当てます。

関連する問題