2010-03-24 141 views
1

我已經通過在這裏閱讀您的優秀答案瞭解到,從foreach循環中刪除項目並不是一個好習慣,因爲它是(我引用)「關閉分支你坐在「。將foreach循環轉換爲while循環的幫助#

我的代碼當前從下拉列表中刪除文本,但實際項目仍然存在(僅顯示文本)。

換句話說,它不是刪除,而且可能不能,因爲你不能從foreach循環中刪除。

經過幾個小時的嘗試,我無法讓我的腦子裏想到這樣做。

//For each checked box, run the delete code 
for (int i = 0; i < this.organizeFav.CheckedItems.Count; i++) 
{ 
    //this is the foreach loop 
    foreach (ToolStripItem mItem in favoritesToolStripMenuItem.DropDownItems) 
    { 
     //This rules out seperators 
     if (mItem is ToolStripMenuItem) 
     { 
      ToolStripMenuItem menuItem = mItem as ToolStripMenuItem; 

      //This matches the dropdownitems text to the CheckedItems String 
      if (((ToolStripMenuItem)mItem).Text.ToString() == organizeFav.CheckedItems[i].ToString()) 
      { 
       //And deletes the item 
       menuItem.DropDownItems.Remove(mItem); 
      } 
     } 
    } 
} 

但它不是刪除,因爲它在一個foreach循環內! 我將非常感謝您的幫助,並且是真正的驚訝,如果任何人都可以解決此代碼:)

親切的問候

回答

3

你不需要一個foreach循環 - 只是使用一個規則的循環,但相反,從最後開始,並開始。

//For each checked box, run the delete code 
for (int i = 0; i < this.organizeFav.CheckedItems.Count; i++) 
{ 
    //this *replaces* the foreach loop 
    for(int j = favoritesToolStripMenuItem.DropDownItems.Count - 1; j >= 0; j--) 
    { 
     ToolStripMenuItem menuItem = favoritesToolStripMenuItem.DropDownItems[j] as ToolStripMenuItem; 

     //This rules out seperators 
     if (menuItem != null) 
     { 
      //This matches the dropdownitems text to the CheckedItems String 
      if (menuItem.Text.ToString() == organizeFav.CheckedItems[i].ToString()) 
      { 
       favoritesToolStripMenuItem.DropDownItems.Remove(menuItem); 
      } 
     } 
    } 
} 

這是@ Kurresmack的代碼重新排列,我只是編碼直接在這裏的頁面,以便原諒任何一個小的語法錯誤或任何明顯的我忽略了(免責聲明:這是一個樣本!)

你可以仍將favoritesToolStripMenuItem.DropDownItems視爲您的集合,但您無需使用foreach對其進行枚舉。這會減少幾行代碼,並且它可以工作,因爲您按照相反的順序迭代它,您將不會得到超出邊界例外的索引。

0

嘗試這樣的事情讓他們的頭:

//For each checked box, run the delete code 
for (int i = 0; i < this.organizeFav.CheckedItems.Count; i++) 
     { 
    List<ToolStripItem> toRemove = new List<ToolStripItem>(); 
//this is the foreach loop 
      foreach (ToolStripItem mItem in favoritesToolStripMenuItem.DropDownItems) 
      { 

       //This rules out seperators 
       if (mItem is ToolStripMenuItem) 
       { 
        ToolStripMenuItem menuItem = mItem as ToolStripMenuItem; 

      //This matches the dropdownitems text to the CheckedItems String 
        if (((ToolStripMenuItem)mItem).Text.ToString() == organizeFav.CheckedItems[i].ToString()) 
        { 
         toRemove.Add(mItem); 
        } 
       } 
      } 
     foreach(var item in toRemove) 
     { 
     favoritesToolStripMenuItem.DropDownItems.Remove(item); 
     } 
     } 
0

在我看來,使代碼工作的方式是:
1.創建一個favoritesToolStripMenuItem.DropDownItems集合類型的實例。
2.在foreach循環中,將不想刪除的所有項目添加到該集合中。
3.使favoritesToolStripMenuItem.DropDownItems指向新的集合。或者清除favoritesToolStripMenuItem.DropDownItems並將新收藏中的物品加載到它。

希望這有助於

0

取而代之的foreach使用反向for -loop:

for(int reverseIndex = myList.Count - 1; reverseIndex >= 0; reverseIndex--) 
{ 
    var currentItem = myList[reverseIndex]; 
    if(MatchMyCondition(currentItem)) 
    { 
     myList.Remove(currentItem); 
    } 
} 
5

樂趣LINQ!

// Loop through the checked items, same as you did. 
foreach (var checkedItem in this.organizeFav.CheckedItems) 
{ 
    // Cast from IEnumerable to IEnumerable<T> so we can abuse LINQ 
    var matches = favoritesToolStripMenuItem.DropDownItems.Cast<ToolStripItem>() 
        // Only items that the Text match 
        .Where(item => item.Text == checkedItem.Text) 
        // Don't match separators 
        .Where(item => item is ToolStripMenuItem) 
        // Select the keys for the later .Remove call 
        .Select(item => item.Name); 

    // Loop through all matches   
    foreach (var key in matches) 
    { 
     // Remove them with the Remove(string key) overload. 
     favoritesToolStripMenuItem.Remove(key); 
    } 
} 
+0

是的,Linq也是我的首選,但我不想嚇倒OP,它的超棒力量:) – slugster 2010-03-24 08:35:12