C#循环和点击事件处理程序

4

如何在迭代中使用单个事件处理程序,而无需硬编码功能?

for (int i = 0; i < 100; i++)
{
        //other code
        PictureBox listItem = new PictureBox();
        listItem.Click += new EventHandler((sender2, e2) => ListItemClicked(i));
        //other code     
}

private void ListItemClicked(int index)
{
    MessageBox.Show(index.ToString());
}

你已经在每次迭代中使用一个处理程序了,是吗?你能否请解释得更详细一些? - Timothy Ghanem
是的,我知道,但是 ListItemClicked() 函数只显示索引 100(最后一个索引),无论我单击哪个 listItem。 - Reese
1个回答

5
你需要将迭代器复制到一个局部变量中,以便委托正确地捕获它:
for (int i = 0; i < 100; i++)
{
        var idx = i;
        //other code
        PictureBox listItem = new PictureBox();
        listItem.Click += new EventHandler((sender2, e2) => ListItemClicked(idx));
        //other code     
}

在你原始的代码片段中,委托表示“返回变量的当前值”,即100,而不是“创建时的值”。 要深入了解此内容,请阅读有关闭包的解释。我建议参考Jon Skeet的"C#深度剖析"。 在C# 5.0中,这种情况已经改变了,但只有对于foreach循环,而不是for i;循环。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接