EventHandlers and the sender

本文关键字:sender the and EventHandlers | 更新日期: 2023-09-27 17:53:00

所以在我的程序中,我创建了一个带有按钮和数字值的结构体…这样的

struct box
    {
        public int numberValue;
        public Button button;
    }
然后我为这个结构体创建了一个二维数组
box[,] boxes = new box[20, 20];

现在我所做的是制作400个按钮并将它们分配给数组的每个索引…这样的

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

现在当我制作事件处理程序时,我想发送"boxes[i,j]"而不仅仅是"boxes[i,j]"。按钮"是否有办法做到这一点?

EventHandlers and the sender

除了定义自己的匿名事件处理程序之外,还有一种简单的方法可以实现您的目的:

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

之后:

private void buttonClick(object sender, EventArgs e)
{
    var box = ((Button)sender).Tag as box;
}

这可以通过匿名事件处理程序来解决。

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

这是用最少的代码最快的解决方案。请注意,匿名事件处理程序因隐藏的陷阱而臭名昭著,需要分配一个新的变量就是一个例子。下面的代码将运行,但无论按下哪个按钮,ij的最后赋值将在处理程序中使用。

boxes[i,j].button.Click += (obj, args) => buttonClick(boxes[i,j], args);

不,这不可能。单个按钮控件是引发事件的按钮控件,因此它是sender参数引用的对象。包含按钮控件的数组不相关。

这个行为是设计出来的。如果您想要更改按钮的属性以响应用户单击它,除非您知道哪个单个按钮被单击,否则这是不可能做到的。只有对包含所有按钮的数组的引用不能提供关于被单击的单个按钮的足够信息。