1

如何使用新创建的 EventHandler 发送变量?我的代码是这样的:

for (int i = 0; i < 5; i++)
{   
    Button buttonX = new Button();
    buttonX.Location = new Point(0, 0 + offset);
    buttonX.Size = new Size(310, 48);
    buttonX.Click += new EventHandler(buttonClick);
}

private void buttonClick(object sender, EventArgs e)
{
    MessageBox.Show();
}

我怎样才能让它像

buttonX.Click += new EventHandler(buttonClick , i);

private void buttonClick(object sender, EventArgs e, int i)
{
    MessageBox.Show(i.toString());
}
4

4 回答 4

8

关闭是盛大的。您可以使用 lambda 表示法:

buttonX.Click += (sender, e) => buttonClick(sender, e, i);

或匿名委托表示法:

buttonX.Click += delegate (object sender, EventArgs e) { buttonClick(sender, e, i); };

但是,如果您捕获循环变量,您将遇到麻烦

相反,做

for (int i = 0; i < 5; i++)
{   
    Button buttonX = new Button();
    buttonX.Location = new Point(0, 0 + offset);
    buttonX.Size = new Size(310, 48);
    var i_copy = i;
    buttonX.Click += (sender, e) => buttonClick(sender, e, i_copy);
}
于 2012-04-19T23:06:04.917 回答
2

鉴于您的情况,只需使用该Tag属性;不要将解决方案与Click事件混为一谈;您不需要i每次都“通过”事件;只需将其标记到控件,因为它始终相同;这样你就不必担心关闭。

将您的代码更改为:

for (int i = 0; i < 5; i++)
{   
    Button buttonX = new Button();
    buttonX.Location = new Point(0, 0 + offset);
    buttonX.Size = new Size(310, 48);
    buttonX.Click += new EventHandler(buttonClick);
    buttonX.Tag = i;
}

private void buttonClick(object sender, EventArgs e)
{
    MessageBox.Show(((Button)sender).Tag.ToString());
}
于 2012-04-19T23:07:43.307 回答
1

你不能这样做,但你可以做的是使用中间 lambda:

for (int i = 0; i < 5; i++)
{
    int j = i; // Need to do this to fix closure issue

    Button buttonX = new Button();
    buttonX.Location = new Point(0, 0 + offset);
    buttonX.Size = new Size(310, 48);
    buttonX.Click += (sender, e) => {
        buttonClick(sender, e, j);
    };
}


private void buttonClick(object sender, EventArgs e, int i)
{
    MessageBox.Show(i.toString());
}
于 2012-04-19T23:07:30.050 回答
1

您将创建一个派生自 EventArgs 的类,该类带有您想要的附加数据点。

http://msdn.microsoft.com/en-us/library/system.eventargs.aspx

因此,您可以为正在进行的事件创建一个 EventArgs,而不是仅仅使用 EventArgs。

public class ButtonClickedEventArgs : EventArgs
{
    public int EventInteger { get; private set; }

    public ButtonClickedEventArgs(int i)
    {
        EventInteger = i;
    }
}

然后,当您引发事件时,您将创建 ButtonClickedEventArgs 类并将其与 EventHandler 一起传递。

于 2012-04-19T23:09:20.533 回答