Question

I am dynamically adding a bunch of controls to a form. Each control calls the same method, and in that method I need to know the array index of the the control that performed the action.

CheckBox[] myCB = new CheckBox[100];
int i;
for (i = 0; i < 100; i++)
{
    myCB[i] = new CheckBox();
    myCB[i].Text = "Clicky!";
    myCB[i].Click += new System.EventHandler(dynamicbutton_Click);
    tableLayoutPanel1.Controls.Add(myCB[i]);
}

private void dynamicbutton_Click(Object sender, System.EventArgs e)
{
    label1.Text = sender.???array index property???.ToString();
}

So if I click myCB[42] label1 will read "42" Of course, if there is an easier way to handle dynamic controls I'd appreciate pointers.

Was it helpful?

Solution

One obvious solution would be to set the tag:

CheckBox[] myCB = new CheckBox[100];
for (int i = 0; i < myCB.Length; i++)
{
    myCB[i] = new CheckBox();
    myCB[i].Text = "Clicky!";
    myCB[i].Click += new System.EventHandler(dynamicbutton_Click);
    myCB[i].Tag = i;
    tableLayoutPanel1.Controls.Add(myCB[i]);
}

Then:

private void dynamicbutton_Click(Object sender, System.EventArgs e)
{
    Control control = (Control) sender;
    label1.Text = sender.Tag.ToString();
}

Another alternative is to capture the information in the event handler, most simply using a lambda expression or anonymous method:

CheckBox[] myCB = new CheckBox[100];
for (int i = 0; i < myCB.Length; i++)
{
    int index = i; // This is very important, as otherwise i will
                  // be captured for all of them
    myCB[i] = new CheckBox();
    myCB[i].Text = "Clicky!";
    myCB[i].Click += (s, e) => label1.Text = index.ToString();
    tableLayoutPanel1.Controls.Add(myCB[i]);
}

or for more complicated behaviour:

CheckBox[] myCB = new CheckBox[100];
for (int i = 0; i < myCB.Length; i++)
{
    int index= i; // This is very important, as otherwise i will
                  // be captured for all of them
    myCB[i] = new CheckBox();
    myCB[i].Text = "Clicky!";
    myCB[i].Click += (s, e) => DoSomethingComplicated(index, s, e);
    tableLayoutPanel1.Controls.Add(myCB[i]);
}

(where you declare DoSomethingComplicated appropriately).

OTHER TIPS

private void dynamicbutton_Click(Object sender, System.EventArgs e)
{
    label1.Text = Array.IndexOf(myCB, (CheckBox)sender).ToString();
}

Control's should have a Tag property. Maybe you can attach the index to the Tag. You will incur boxing though...

int j = i;
myCB[i].Click += delegate(object sender, EventArgs e) {
 // here you can use "j"

};
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top