始终在foreach循环中使用相同的值调用事件处理程序

时间:2014-09-22 12:16:26

标签: c# user-interface lambda callback

我想将一组回调函数绑定到C#中的GUI元素,每个函数使用不同的参数调用相同的处理函数。

拼写方式

# Assign element #1 to widget

widget.Click += () => {ProcessClick(1) ;} ;

# Assign element #2 to widget

widget.Click += () => {ProcessClick(2) ;} ;

...

似乎多余。但是,一个天真的循环

Widget widget ;

foreach (int i in new List<int>() {0, 1, 2, 3, 4, 5, 6, 7, 8, 9} )
{
    # Assign element i to widget

    widget.Click += () => {ProcessClick(i) ;} ;
}

将无效,因为一旦调用任何回调,循环将过期,从而导致为每个小部件调用ProcessClick(9)

我觉得应该有一个简单的解决方案,但我被卡住了。

如何将回调函数绑定到GUI元素,每个GUI元素调用具有不同参数的函数而不将它们全部拼写出来?

1 个答案:

答案 0 :(得分:5)

在循环期间,您的代理会捕获

i。您需要将其值复制到循环中的局部变量才能使其正常工作:

Widget widget ;

foreach (int i in new List<int>() { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 } )
{
    # Assign element i to widget

    int index = i;
    widget.Click += () => {ProcessClick(index) ;} ;
}

有关变量捕获的更多信息可以在hereEric Lipper's blog找到。对于后者,您还可以找到有关C#团队在C#5中进行的重大更改的信息,其中变量在逻辑上位于循环内(如DavidG所述)。