LukAss741
LukAss741

Reputation: 831

Pass variables to Click event

I have following code for creating dynamic buttons but message box allways shows 8. How would I make it show in example 4 when I click button[0][4]? I have tried labda and delegate but both allways return 8 (text[i].Count). The same things happen to variable i. It must be something very simple but I can't find it :-(.

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

Upvotes: 2

Views: 153

Answers (2)

Simon Whitehead
Simon Whitehead

Reputation: 65107

Since SLaks hasn't yet given an example.. I will. Here is a small re-creation of your issue:

internal class Test
{
    public EventHandler Click;
}

..then main method:

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
}

You need to create a local variable inside the loop, so each closure gets its own copy:

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
}

Which produces the correct output.

Upvotes: 2

SLaks
SLaks

Reputation: 888263

You're capturing the loop variable inside the closure.
When the event fires, that variable is always equal to the last item.

Instead, you need to declare separate variables inside the loop, so each each lambda will capture its own variable that never changes.

Upvotes: 4

Related Questions