2014-03-29 115 views
1

我在Microsoft Visual Studio 2012中使用C#。 我有一個程序在其中創建一組按鈕,所有都被分配了相同的事件處理程序。 (花哨的方式讓用戶選擇一個選項。)一旦選擇了這個選項,我需要銷燬所有這些按鈕。我一直在使用下面的代碼:C#一次刪除多個按鈕

foreach (Control c in this.Controls) 
{ 
    if (c.GetType() == typeof(Button)) 
    { 
     c.Click -= new EventHandler(TeamChoiceButton_Click); 
     this.Controls.Remove(c); 
     c.Dispose(); 
    } 
} 

問題是它是刪除其他每個按鈕。我假設,因爲我在foreach中刪除了它們,所以它調整了索引,使其跳過其他所有索引。什麼是正確的方法來做到這一點?任何幫助將不勝感激,特別是如果我誤解爲什麼它跳過其他按鈕。

+1

將它們放在面板和迭代'panel.Controls' – etaiso

+1

使用'for'索引到列表和重複最後一個到第零個。 –

+0

當你說'每個其他按鈕',你是說它正在刪除你不想刪除的按鈕,或者它只是刪除了一半的按鈕? –

回答

2

你可以把所有你快速進入List<Button>創建按鈕,當您創建 然後使用:

foreach (Button b in myButtonList) 
{ 
    this.Controls.Remove(b); 
} 
myButtonList.Clear(); 
4

值的按鈕的Tag屬性添加,以紀念他們爲稍後刪除。

var btn = new Button(); 
btn.Tag = new object(); 
btn.Text = "xy"; 
... 
this.Control.Add(btn); 

然後你可以將其刪除:

var myButtons = this.Controls 
    .OfType<Button>() 
    .Where(b => b.Tag != null) 
    .ToList(); //Because you cannot modify the collection being iterated with for each. 
foreach (Button b in myButtons) { 
    b.Click -= new EventHandler(TeamChoiceButton_Click); 
    this.Controls.Remove(b); 
    b.Dispose(); 
} 

LINQ到對象查詢的懶惰的方式執行。這意味着如果我們不在查詢中添加.ToList(),則查詢會按照foreach循環進行評估。枚舉Controls集合時刪除Controls集合中的控件將引發異常。 .ToList()強制過早評估查詢,從而消除該問題。

+0

我最終使用了列表後面的迭代,但是我想喜歡解釋上面的代碼,看看我是否理解它。 myButtons var是this.Controls的引用變量。和各種.OfType和.Where Linq函數來操縱列表。 .ToList將其從任何類型的控件(IEnumerable?)更改爲實際的IList類型。由於我遍歷引用變量,所以如果我更改數據變量this,它的索引不會改變。控件 –

+0

'OfType ()'和'Where(...)'是應用於枚舉控件的過濾器。 'Controls'屬性。如果沒有'ToList()''myButtons'變量只會是一個無用的查詢,直到'foreach'語句執行查詢。使用'ToList()'調用立即執行查詢,'myButtons'變成'List

3

您可以通過列表向後迭代和刪除的項目那樣:

for (int i = this.Controls.Count - 1; i >= 0; i--) 
{ 
    Control c = this.Controls[i]; 
    if (c.GetType() == typeof (Button)) 
    { 
     c.Click -= new EventHandler(TeamChoiceButton_Click); 
     this.Controls.RemoveAt(i); 
     c.Dispose(); 
    } 
} 
+0

感謝這工作完全根據需要(也感謝安德魯莫頓相同的答案)。 –