2010-03-24 210 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