2014-01-10 5 views
2

동적 버튼을 생성하기위한 다음 코드가 있습니다. 그러나 메시지 상자에 항상 8이 표시됩니다. button[0][4]을 클릭하면 어떻게 예 4에 표시됩니까? 나는 labda를 시도하고 위임하지만 둘 다 항상 8 (text[i].Count)을 반환합니다. 같은 일이 변수 i에 발생합니다. 그것은 매우 간단한 것이어야하지만 난 :-(을 찾을 수 없습니다.클릭 이벤트에 변수 전달

private void Form1_Load(object sender, EventArgs e) 
{ 
    for(int i = 0; i < text.Count; i++) // text.Count is 3 
    { 
     for(int a = 0; a < text[i].Count; a++) // text[i].Count is 8 
     { 
      button[i][a].Location = new Point(230, 30 +22 *a); 
      button[i][a].Text = "Done" + i + " " + a; 
      button[i][a].Click += delegate { click(a); }; 
... 

private void click(int a) 
{ 
    MessageBox.Show("" +a); 
} 

답변

4

당신은 폐쇄 내부 루프 변수를 캡처하고 있습니다.
언제 이벤트가 발생, 그 변수는 항상 동일 마지막 항목.

대신, 당신은 루프 내에서 별도의 변수를 선언해야하므로 각 각 람다는 변경되지 않습니다 자신의 변수를 캡처합니다. SLaks 이후

+0

"깨는 변화"가 언젠가 곧 발생하지 않았습니까? 변수가 루프 내부 어디에 있습니까? –

+0

확실하지는 않지만이 특별한 경우에는 참조 유형이 아닌 int를 사용하고 있습니다. 그래서 모든 것이 잘 될 것 같습니다. – Anarion

+0

@SLaks 'int newVariable = a' 및'delegate {click (newVariable);};이 선언문은이 문제를 해결할 것이라고 말하고 싶습니까? 나는 그것이 마지막 값을 고를 것이라는 점에 동의하지만 새로운 변수를 선언하는 것이 이것을 해결할 것이라고 확신하지는 않는다 ... 나는 이것이 다른 해결책을 필요로한다고 생각한다. – CarbineCoder

2

가 아직 예를 작성하지 않았습니다 ...... 나는 것입니다. 다음은 문제의 재 작성입니다.

internal class Test 
{ 
    public EventHandler Click; 
} 

..then 주요 방법 :

var list = new List<Test>(); 

for (int i = 0; i < 6; i++) 
{ 
    Test t = new Test(); 
    t.Click += delegate 
    { 
     click(a); 
    }; 

    list.Add(t); 
} 

foreach (var t in list) 
{ 
    t.Click(null, null); // 6, 6, 6, 6, 6 
} 

당신은 루프 내부의 지역 변수를 생성해야하므로 각 폐쇄는 자신의 복사본을 가져옵니다

var list = new List<Test>(); 

for (int i = 0; i < 6; i++) 
{ 
    int a = i; /* <--------------- THIS LINE HERE ------------------ */ 
    Test t = new Test(); 
    t.Click += delegate 
    { 
     click(a); // use the new variable here 
    }; 

    list.Add(t); 
} 

foreach (var t in list) 
{ 
    t.Click(null, null); // 0, 1, 2, 3, 4, 5 
} 

올바른 출력을 생성 .

관련 문제