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);

}

助けてくれてありがとう!

フロリアン

4

2 に答える 2

4

これは、カウンター変数がキャプチャされないためです。これは、ループが終了すると、counterの値が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);

}

詳細については、stackoverflowに関するこの質問を参照してください。C#のループでキャプチャされた変数

于 2012-11-23T08:47:48.640 に答える
2

これは、デリゲートがではなく変数の参照をキャプチャするためです。つまり、10個のデリゲートすべてに、まったく同じ変数への参照が含まれています。デリゲートを実行すると、ループはすでに終了しているため、この変数の値は当然10になります。countercounter

次のように修正します。

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

これで、各デリゲートは独自のインスタンスを持つことになります。

ところで、ラムダ構文を使用して、このコードを少し冗長にすることができます。

var tmp = counter;
btn.Click += (sender1, e1) => myEventHandler(sender1, e1, tmp);
于 2012-11-23T08:47:06.960 に答える