I’m creating an array of controls and adding them to the form, and setting their events to a function that receives the index of the clicked button using a lambda expression (b.Click += (sender, e) => myClick(i);).
But the problem is… Whichever you click on, you receive the index 100, not the real index of the button! What is the problem here?
namespace testArrayOfControls
{
public partial class Form1 : Form
{
Button[] buttons;
public Form1()
{
InitializeComponent();
buttons = new Button[100];
for (int i = 0; i < 100; i++)
{
buttons[i] = new Button();
buttons[i].SetBounds(i % 10 * 50, i / 10 * 50, 50, 50);
buttons[i].Click += (sender, e) => myClick(i);
this.Controls.Add(buttons[i]);
}
}
private void myClick(int i)
{
MessageBox.Show(i.ToString());
}
}
}
The problem is that you create closure over the loop variable
i. You need to make a local (inside theforloop) copy of it before passing it to the event handler.Explanation
You are defining a function like this:
This function (which will run at some point in the future, when the button is clicked) includes a reference to
i. The way, this works is that it will use the value ofiat the time when the click occurs, not at the time the function is defined.By that time, clearly the value of
iwill have become 100.The solution works because it makes the function take a reference to the variable
indexinstead ofi.indexdiffers fromiin thatiis one variable whose value changes, whileindexis a name we use for 100 different variables (one for each loop iteration), the value of which remains constant.