【问题标题】:Bind Event Handlers within a loop在循环中绑定事件处理程序
【发布时间】:2018-11-16 14:55:44
【问题描述】:

我正在尝试将事件绑定到在 for 循环中创建的动态创建的菜单项的单击事件。当我单击菜单项时,代码会执行,但它是循环中的最后一个值“x”。这是代码:

        for(int x = 1; x < 3; x++)
        {
            MenuItem mi = new MenuItem("Get");
            ContextMenu cm = new ContextMenu();
            mi.Click += (s, e) => { GetClick(x); };
            cm.MenuItems.Add(mi);
            Button btn = this.Controls.Find("btnGet" + x.ToString(), true).FirstOrDefault() as Button;
            btn.ContextMenu = cm;

        }

    private void GetClick(int intGetItem)
    {
        //Previous code...

        GetItem(intGetItem);
    }

问题是当我调试 GetClick 方法时,无论我使用哪个按钮,intGetItem 始终等于 3。任何帮助表示赞赏!

【问题讨论】:

    标签: c# winforms events


    【解决方案1】:

    您需要将 x 分配给一个局部变量并在您的表达式中使用它:

    var y = x;
    mi.Click += (s, e) => { GetClick(y); };
    

    这里有一个解释:https://blogs.msdn.microsoft.com/ericlippert/2009/11/12/closing-over-the-loop-variable-considered-harmful/

    【讨论】:

      【解决方案2】:

      注册时不能定义事件的参数。相反,您应该传递菜单项将提供的参数。

      mi.Click += GetClick;
      

      并更改您的事件以获取标准点击参数:

      private void GetClick(object sender, EventArgs e)
      {
          if (sender == menu1) {...
      

      【讨论】:

      • 我不明白你的话。在他的例子中,事件处理程序是 LINQ 表达式 (s, e) => ... 这没问题。
      • @Klaus Gütter - 哦,对不起,我错过了那一点。我不确定 OP 是否只是使用错误的语法来做一些简单的事情,或者试图做一些我不理解的复杂事情。我将针对简单案例编辑我的答案。
      猜你喜欢
      • 2012-01-27
      • 2015-04-05
      • 1970-01-01
      • 2011-04-01
      • 1970-01-01
      • 1970-01-01
      • 2017-10-05
      • 2010-10-22
      • 1970-01-01
      相关资源
      最近更新 更多