Lambda 表达式在设置某些控件的事件处理程序时不起作用

2024-02-08

我正在创建一个控件数组并将它们添加到表单中,并将它们的事件设置为一个函数,该函数使用 lambda 表达式接收单击的按钮的索引(b.Click += (sender, e) => myClick(i);).

但问题是...无论你点击哪个,你收到的索引都是100,而不是按钮的真实索引!这里有什么问题?

namespace testArrayOfControls
{

    public partial class Form1 : Form
    {
        Button[] buttons;

        public Form1()
        {
            InitializeComponent();
            buttons = new Button[100];
            for (int i = 0; i < 100; i++)
            {
                buttons[i] = new Button();
                buttons[i].SetBounds(i % 10 * 50, i / 10 * 50, 50, 50);
                buttons[i].Click += (sender, e) => myClick(i);
                this.Controls.Add(buttons[i]);
            }
        }

        private void myClick(int i)
        {
            MessageBox.Show(i.ToString());
        }

    }
}

问题是你在循环变量上创建了闭包i。你需要做一个本地的(在for循环)在将其传递给事件处理程序之前复制它。

for (int i = 0; i < 100; i++)
{
    var index = i; // YOU NEED TO DO THIS
    buttons[i] = new Button();
    buttons[i].SetBounds(i % 10 * 50, i / 10 * 50, 50, 50);
    buttons[i].Click += (sender, e) => myClick(index); // THIS SOLVES THE PROBLEM
    this.Controls.Add(buttons[i]);
}

解释

您正在定义这样的函数:

(sender, e) => myClick(i)

此函数(将在将来的某个时刻,当单击按钮时运行)包含对i。其工作方式是,它将使用i 当点击发生时,不是在定义函数时。

到时候,价值就一目了然了i将变成 100。

该解决方案有效,因为它使函数引用变量index代替i. index不同于i在那里面i是一个其值发生变化的变量,而index是我们用于 100 个不同变量的名称(每个循环迭代一个变量),其值保持不变.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Lambda 表达式在设置某些控件的事件处理程序时不起作用 的相关文章

随机推荐