0

Here's some sample code which denotes my problem. It adds 5 LinkLabels, each with a Click event handler. The text on the label is 1...5 and should display the same result when clicked, but when I click on each of the labels I get the same message for each: 5.

It's like the last handler is overwriting the handler on each of the other labels. I thought I had avoided that by creating a new EventHandler and new LinkLabel each iteration of the loop.

I added each LinkLabel to a FlowLayoutPanel.

Why am I getting this result, and how can I fix it?

List<Test> objects = new List<Test>();
for (int i = 0; i < 5; i++)
{
    objects.Add(new Test(i + 1));
}

foreach (Test t in objects)
{
    LinkLabel label = new LinkLabel();
    label.AutoSize = true;
    label.Text = t.a + "";

    label.Click += new EventHandler((sender, args) =>
    {
        MessageBox.Show(t.a + "");
    });

    flowLayoutPanel1.Controls.Add(label);
}
J0e3gan
  • 8,740
  • 10
  • 53
  • 80
kschieck
  • 1,407
  • 2
  • 16
  • 29

1 Answers1

1

In my attempt to reproduce the problem you described with your code, the link labels 1 through 5 displayed 1 through 5 respectively when clicked just like you want.

Here is a standalone example that minimally builds upon the code you posted (just to the extent necessary to make it build and run)...and works as expected:

// FORNOW: Added Main method for PoC.
void Main()
{
    // FORNOW: Added necessary Form and FlowLayoutPanel locals.
    Form form1 = new Form();
    FlowLayoutPanel flowLayoutPanel1 = new FlowLayoutPanel();

    List<Test> objects = new List<Test>();
    for (int i = 0; i < 5; i++)
    {
        objects.Add(new Test(i + 1));
    }

    foreach (Test t in objects)
    {
        LinkLabel label = new LinkLabel();
        label.AutoSize = true;
        label.Text = t.a + "";

        label.Click += new EventHandler((sender, args) =>
        {
            MessageBox.Show(t.a + "");
        });

        flowLayoutPanel1.Controls.Add(label);
    }

    // FORNOW: Added necessary control wiring and display call.
    form1.Controls.Add(flowLayoutPanel1);
    form1.Show();
}

// FORNOW: Added a Test class based on the OP's code.
public class Test
{
    public int a { get; set; }

    public Test(int a)
    {
        this.a = a;
    }
}

You may have a problem in other code you are employing, but the code you shared works fine based on what you said you expect.

J0e3gan
  • 8,740
  • 10
  • 53
  • 80
  • Hm, that's weird, I'm still getting the same problem. each of the labels when clicked sends the message "5" – kschieck Oct 15 '14 at 03:46
  • Got it, for some reason it was referencing the same object. so when I created a variable like `string a = t.a + " ";` then it would contain the right values; – kschieck Oct 15 '14 at 03:50
  • @kschieck, the reason would be in the state of the code before you (changed it and) "got it": you should post an answer that explains the solution once you have isolated it. You should also consider upvoting my answer if it proved useful. :} – J0e3gan Oct 15 '14 at 04:27