2

So in my program i created a struct with a button and a number value... like this

struct box
    {
        public int numberValue;
        public Button button;
    }

I then made a 2D array of this struct

box[,] boxes = new box[20, 20];

Now what i did was make 400 buttons and assigned them to each index of the array... like this

        private void createBoxes()
    {
        int positionX;
        int positionY;
        for (int i = 0; i < 20; i++)
        {
            for (int j = 0; j < 20; j++)
            {
                positionX = 20 + (25 * i);
                positionY = 20 + (25 * j);
                boxes[i, j].button = new System.Windows.Forms.Button();
                boxes[i, j].button.Location = new System.Drawing.Point(positionX,positionY);
                boxes[i, j].button.Size = new System.Drawing.Size(25, 25);
                this.Controls.Add(boxes[i, j].button);
                boxes[i, j].button.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
                boxes[i, j].button.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
                boxes[i, j].button.Visible = true;
                boxes[i, j].button.Name = "button";
                boxes[i, j].button.Click += new EventHandler(buttonClick);
            }
        }
    }

Now when i make the event handler i want to send "boxes[i,j]" not just "boxes[i,j].button" is there anyway to do this?

Nick
  • 21
  • 1

3 Answers3

4

Short of defining your own anonymous event handler, there's an easy way to do what you want:

boxes[i, j].button.Tag = boxes[i, j];

Then later:

private void buttonClick(object sender, EventArgs e)
{
    var box = ((Button)sender).Tag as box;
}
Matt Hamilton
  • 200,371
  • 61
  • 386
  • 320
3

This can be solved via an anonymous event handler.

var box = boxes[i, j]; // You must use a new variable within this scope
box.button.Click += (obj, args) => buttonClick(box, args);

This is the quickest solution with the least code. Just be aware that anonymous event handlers are notorious for hidden gotchas, and the need to assign a new box variable is an example. The following code will run, but no matter which button you press, the last-assigned values of i and j would be used within the handler.

boxes[i,j].button.Click += (obj, args) => buttonClick(boxes[i,j], args);
Andrew Shepherd
  • 44,254
  • 30
  • 139
  • 205
0

No, this is not possible. The individual button control is the one that raises the event, thus it is the object referenced by the sender parameter. The array that contains the button control is irrelevant.

This behavior is by-design. If you wanted to change a property of the button in response to the user clicking on it, it would be impossible to do unless you knew which individual button was clicked. Having only a reference to the array that contains all of the buttons would not provide sufficient information about the individual button that was clicked.

Cody Gray - on strike
  • 239,200
  • 50
  • 490
  • 574