【问题标题】:Pass variables to Click event将变量传递给 Click 事件
【发布时间】:2014-01-28 21:56:22
【问题描述】:

我有以下用于创建动态按钮的代码,但消息框总是显示 8。当我单击 button[0][4] 时,如何使其显示在示例 4 中?我已经尝试过 labda 和 delegate 但都返回 8 (text[i].Count)。同样的事情也发生在变量i 上。 它一定很简单,但我找不到:-(。

private void Form1_Load(object sender, EventArgs e)
{
    for(int i = 0; i < text.Count; i++) // text.Count is 3
    {
        for(int a = 0; a < text[i].Count; a++) // text[i].Count is 8
        {
            button[i][a].Location = new Point(230, 30 +22 *a);
            button[i][a].Text = "Done" + i + " " + a;
            button[i][a].Click += delegate { click(a); };
...

private void click(int a)
{
    MessageBox.Show("" +a);
}

【问题讨论】:

    标签: c# button parameters click


    【解决方案1】:

    您正在捕获闭包内的循环变量。
    当事件触发时,该变量始终等于最后一项。

    相反,您需要在循环内声明单独的变量,因此每个 lambda 都会捕获自己的永不改变的变量。

    【讨论】:

    • 这种“重大变化”不是很快就会发生吗……?变量在循环内的什么位置?
    • 我不确定,但在这种特殊情况下,他使用的是 int,而不是引用类型。所以看起来一切都会好起来的
    • @SLaks 你的意思是说声明int newVariable = a 和delegate { click(newVariable);}; 会解决这个问题吗?我同意它将获取最后一个值,但我不太确定声明一个新变量会解决这个问题......我认为这需要一个不同的解决方案。
    • @SimonWhitehead:不;这仅针对引用类型进行了更改。
    • @BharathramAttiyannan:错误;在循环内声明的变量将在每次迭代时创建一个单独的闭包。在 Javascript 中,这是行不通的。
    【解决方案2】:

    由于 SLaks 还没有给出一个例子.. 我会的。这是您的问题的一个小重新创建:

    internal class Test
    {
        public EventHandler Click;
    }
    

    ..然后是主要方法:

    var list = new List<Test>();
    
    for (int i = 0; i < 6; i++)
    {
        Test t = new Test();
        t.Click += delegate
        {
            click(a);
        };
    
        list.Add(t);
    }
    
    foreach (var t in list)
    {
        t.Click(null, null); // 6, 6, 6, 6, 6
    }
    

    你需要在循环中创建一个局部变量,所以每个闭包都有自己的副本:

    var list = new List<Test>();
    
    for (int i = 0; i < 6; i++)
    {
        int a = i; /* <--------------- THIS LINE HERE ------------------ */
        Test t = new Test();
        t.Click += delegate
        {
            click(a); // use the new variable here
        };
    
        list.Add(t);
    }
    
    foreach (var t in list)
    {
        t.Click(null, null); // 0, 1, 2, 3, 4, 5
    }
    

    这会产生正确的输出。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-07-11
      • 1970-01-01
      • 1970-01-01
      • 2023-03-08
      • 1970-01-01
      • 2022-09-30
      • 1970-01-01
      相关资源
      最近更新 更多