使用代码C#添加行为来控制

时间:2018-01-02 23:03:28

标签: c# behavior

我正在使用Visual Studio 2017和C#来创建Win Form应用程序。我正在尝试将鼠标输入行为添加到一组控件中,如下所示;

int i = 0;
foreach(MetroTileItem item in game_tile_panel.Items){

        // THIS MESSAGE BOX DISPLAYS THE CORRECT VALUE
        MessageBox.Show(i.ToString());

        item.MouseEnter += (Object sender, EventArgs e) => {
             // THIS MESSAGE BOX DOES NOT DISPLAY TO CORRECT VALUES
             MessageBox.Show(i.ToString());
        };

        i++;
}

第一个消息框为每个项目返回i的值并正确显示。 MouseEnter行为中的第二个消息框不会显示i的正确值,也不会显示我期望的值。

当我在运行时执行MouseEnter行为时,消息框会为每个项目显示值3。我希望第一项显示0,第二项1等。

任何人都可以解释为什么会发生这种情况以及如何解决这个问题。也许我无法以这种方式添加行为?感谢

2 个答案:

答案 0 :(得分:1)

int i = 0;
foreach(MetroTileItem item in game_tile_panel.Items){

    int pickMe = i;    <<<<<<<<<<<<<

    // THIS MESSAGE BOX DISPLAYS THE CORRECT VALUE
    MessageBox.Show(i.ToString());

    item.MouseEnter += (Object sender, EventArgs e) => {
         // THIS MESSAGE BOX DOES NOT DISPLAY TO CORRECT VALUES
         MessageBox.Show(pickMe.ToString());   <<<<<<<<<<<<<<<<
    };

    i++;
}

通过为每次迭代声明一个新变量,可以捕获正确的值。直到foreach完成后某个时间才调用事件处理程序的事实是原因。

答案 1 :(得分:1)

这是modified closure现象的一个实例:简而言之,您声明为事件处理程序的委托捕获变量 i,而不是当前值我这称为闭包。因此,每个事件处理程序在调用它时将值3取消引用,因为这是在循环退出时你离开i的方式。

博客文章解释了如何使用局部变量来规避这一点。

相关问题