2012-11-23 88 views
3

我將在C#中創建動態按鈕,並且需要向Click-Event-Handler(ID)添加一個參數。帶代表的事件處理程序

但是,在這個例子中,輸出總是最後一個參數「10」所有按鈕,而不是「1-2-3-4-5 -....」,爲什麼?

for(int counter = 1; counter < 10; counter++) 
{ 

    // Add new button 

    Button btn = new Button(); 

    btn.Width = 250; 
    btn.Height = 50; 

    btn.Click += delegate (object sender1, EventArgs e1) 
    { myEventHandler(sender1, e1, counter); }; 

    Test.Controls.Add(btn); 

} 


public void myEventHandler(object sender, EventArgs e, int i) 
{ 

    MessageBox.Show("Test: " + i); 

} 

Thanx的任何幫助!

弗洛裏安

回答

3

這是因爲計數器變量沒有捕獲。這意味着,當循環結束計數器的值是10,因此,所有與會代表將有一個價值修復,你可以像這樣在循環中使用的變量:

for(int counter = 1; counter < 10; counter++) 
{ 

    // Add new button 

    Button btn = new Button(); 

    btn.Width = 250; 
    btn.Height = 50; 

    int num = counter; 
    btn.Click += delegate (object sender1, EventArgs e1) 
    { myEventHandler(sender1, e1, num); }; 

    Test.Controls.Add(btn); 

} 


public void myEventHandler(object sender, EventArgs e, int i) 
{ 

    MessageBox.Show("Test: " + i); 

} 

查看計算器這個問題的更多信息Captured variable in a loop in C#

2

這是因爲委託捕獲counter變量的參考而不是。這意味着所有十位代表都包含對同一個變量counter的引用。在執行代表時,這個變量自然具有值10,因爲你的循環已經完成。

修復這樣的:

var tmp = counter; 
btn.Click += delegate (object sender1, EventArgs e1) 
{ myEventHandler(sender1, e1, tmp); }; 

現在每個代表都有自己的實例。

順便說一句,你可以使用lambda語法,使這個代碼少一些冗長:

var tmp = counter; 
btn.Click += (sender1, e1) => myEventHandler(sender1, e1, tmp);