在设置一些控件的事件处理Lambda表达式不工作 [英] Lambda expression not working in setting the event-handler of some controls

查看:160
本文介绍了在设置一些控件的事件处理Lambda表达式不工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建控件数组,并将它们添加到窗体,并设置自己的事件接收点击的按钮使用lambda表达式的指数函数( b.Click + =(发件人,E)=> MyClick认证(I);


$ b $无论你点击第b

但问题是......,您会收到索引100中,而不是按钮的实折射率!什么是这里的问题。



 命名空间testArrayOfControls 
{

公共部分Form1类:表
{
键[]按钮;

公共Form1中()
{
的InitializeComponent();
键=新的Button [100];
的for(int i = 0; I< 100;我++)
{
按钮[i] =新的Button();
按钮[I] .SetBounds(ⅰ%10 * 50,I / 10 * 50,50,50);
按钮[i]。点击+ =(发件人,E)=>了MyClick(ⅰ);
this.Controls.Add(按钮[I]);
}
}

私人无效了MyClick(int i)以
{
MessageBox.Show(i.ToString());
}

}
}


解决方案

的问题是,您在循环变量创建封我。你需要将它传递给事件处理程序之前进行局部的它(循环内)的副本。

 的for(int i = 0; I< 100;我++)
{
变种指数= I; //你需要这样做
按钮[i] =新的Button();
按钮[I] .SetBounds(ⅰ%10 * 50,I / 10 * 50,50,50);
按钮[i]。点击+ =(发件人,E)=> MyClick认证(指数); //这解决了问题
this.Controls.Add(按钮[I]);
}



说明



您正在定义这样的功能:

 (发件人,E)=> MyClick认证(I)

这功能(这将在未来的某个时刻,当按钮运行点击)包括对 I 的参考。 ,其工作原理是,它会在的时候发生的点击,而不是当时的函数定义的使用 I



到那个时候, I 将成为100。

$ b $明确的价值b

解决方案的工作,因为它使函数取到变量的引用首页而不是 I 首页不同我 I 是一个变量,其值的变化,而首页是我们使用100种不同的变量(每个循环迭代)的名称,,它的值保持不变


I'm creating an array of controls and adding them to the form, and setting their events to a function that receives the index of the clicked button using a lambda expression (b.Click += (sender, e) => myClick(i);).

But the problem is... Whichever you click on, you receive the index 100, not the real index of the button! What is the problem here?

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());
        }

    }
}

解决方案

The problem is that you create closure over the loop variable i. You need to make a local (inside the for loop) copy of it before passing it to the event handler.

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]);
}

Explanation

You are defining a function like this:

(sender, e) => myClick(i)

This function (which will run at some point in the future, when the button is clicked) includes a reference to i. The way, this works is that it will use the value of i at the time when the click occurs, not at the time the function is defined.

By that time, clearly the value of i will have become 100.

The solution works because it makes the function take a reference to the variable index instead of i. index differs from i in that i is one variable whose value changes, while index is a name we use for 100 different variables (one for each loop iteration), the value of which remains constant.

这篇关于在设置一些控件的事件处理Lambda表达式不工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆