English 中文(简体)
创建 MouseEventHandler 的代表新实例
原标题:creating delegate new instance of MouseEventHandler

当动态地创建按钮时, 我希望有一个新的鼠标EventHandler。 我这么做了,

this.Controls[btnAdd.Name].MouseClick += new MouseEventHandler(generalMethods.generatePopup());

然而,由于我需要将参数传递到事件上,我让生成Popup接受了一个表示纽扣号的整数(这样我就可以进一步使用 ) 。 在过去,我本来只是用匿名代表来传递额外的参数,但是这似乎不像我想创建一个新例子那样有效;

this.Controls[btnAdd.Name].MouseClick += delegate(object sender, MouseEventArgs e) { new MouseEventHandler( generalMethods.generatePopup(sender, e, i); };

错误似乎出现在新的鼠标EventHandler上。 如果我把它拿出来, 效果会很好, 我可以传递更多数据, 但是因为这不是一个新例子, 它不会给每个按钮自己带来事件, 比如这样;

this.Controls[btnAdd.Name].MouseClick += new MouseEventHandler(generalMethods.generatePopup());

有人知道如何围绕这个问题开展工作吗?例如,仍然使用anon delegation 的方法,但仍然在创造新的事件实例吗?

EDIT:嗯,我尝试过这个(参数通过,罚款,我相信),但似乎它不是为每个按钮创建一个新的鼠标活动处理器,而是对所有按钮都使用同样的按钮,因为我设置了一个标签来测试它是否获得了正确的按钮编号,但是弹出时的所有标签都返回了最后一个按钮编号,而不是正确的。有什么想法吗?

EDIT2:这是我用来生成按钮的代码块:

 for (int i = 0; i <= count && i < 2; i++)
        {

            Button btnAdd = new Button();
            btnAdd.Text = dataTable.Rows[i]["deviceDescription"].ToString();
            btnAdd.Location = new Point(x, y);
            btnAdd.Tag = i;
            btnAdd.Name = "btn" + i.ToString();
            btnAdd.BackColor = Color.Green;

            this.Controls.Add(btnAdd);

            this.Controls[btnAdd.Name].MouseClick += (sender, e) =>
{
    int index = i;
    generalMethods.generatePopup(sender, e, index);
};

这是我的生成Popup方法, 即鼠标EventHandler:

public void generatePopup(object sender, MouseEventArgs e, int buttonNumber)
    {
      //  DBConnector mDBConnector = new DBConnector();
      //  DataTable dataTable = mDBConnector.Select("SELECT * FROM devices WHERE deviceID = " + buttonNumber);


        DeviceBreakdownPopup popupDevice = new DeviceBreakdownPopup();
        popupDevice.lblDeviceNo.Text = buttonNumber.ToString();

        PopupWindow popup = new PopupWindow(popupDevice);
        popup.Show(Cursor.Position);

    }

此处显示发生的一切,只是为了清楚起见:

"https://i.sstatic.net/j3nWd.png" alt="错误的示例"/ >

这里我们看到两个弹出用户控件都给标签为“ 2 ”, 而我需要每个都具有正确的值, “ 1” 和“ 2 ” 。

最佳回答

尝试此 :

this.Controls[btnAdd.Name].MouseClick += new MouseEventHandler(
    (sender, evt) => {
        generalMethods.generatePopup()
    }
);

new mouseEventHandler (...) 部分是可选的 - 汇编者从 任务左侧计算参数类型 。

您的代码问题在于 it accesses 修改关闭 。 您应该从 > i 做一个临时变量, 并在您的 lambda 中用它来修正问题 。

for (int i = 0; i <= count && i < 2; i++)
    {

        Button btnAdd = new Button();
        btnAdd.Text = dataTable.Rows[i]["deviceDescription"].ToString();
        btnAdd.Location = new Point(x, y);
        btnAdd.Tag = i;
        btnAdd.Name = "btn" + i.ToString();
        btnAdd.BackColor = Color.Green;

        this.Controls.Add(btnAdd);
        var temp = i;
        this.Controls[btnAdd.Name].MouseClick += (sender, e) =>
            {
            int index = temp;
            generalMethods.generatePopup(sender, e, index);
        };
}
问题回答

generatePopup 返回什么类型? 如果它返回了 MouseEventHandler 已经返回了 , 那么您应该没事( 只要为每个实例产生一个新的处理器 ) 。 类似 :

btnAdd.MouseClick += generalMethods.generatePopup();

/* in generalMethods */
private static int ButtonIndex = 0;
public MouseEventHandler generatePopup()
{
   int tempIndex = ButtonIndex++;
   return new MouseEventHandler((sender, ea) => generalMethods.generatePopup(sender, ea, tempIndex));
}

您之所以这样做,是因为 < code>generatePopup 方法将为每个按钮创建一个新的 < code> MouseEventHandler 。 生成的每个处理器将为您创建的羊羔创建一个关闭点, 添加我们设置为本地域的 < code> tempdex 变量。 因此, 当处理器创建时, 对羊羔( 包括 temIndex) 创建新的关闭点, 并将为每个单个按钮调用生成Popup方法( 这是 Temindex 的本地版本) 。 对变量的关闭会发生在 Lambda 外部, 所以您应该设置一个本地变量 < em > 之前 < / em > 。 您可以指定 Lambda, 并且会被正确捕获 。

试一试,让我们知道

编辑 : 因此我看到你在循环中生成按钮。 是否有动态生成这些按钮的情况 (IE: 不在该循环中, 在初始创建之后的某个时候)? 如果是这样的话, 您已经掌握了按钮本身上的所有信息 :

(sender, ea) => generalMethods.generatePopup(sender, ea, (int)((Control)sender).Tag)

既然您已经将索引附加到标签中, 您就不必为不同按钮的索引的不同版本操心。 在您当前版本中, 您正在试图获取循环变量本身的引用( 被重新使用), 所以当您在循环中重新使用鼠标EventHandler的所有实例时, 您在最终状态 < / 坚固 > 中引用循环变量 < 坚固 > 。 循环变量和兰巴达斯不会混合, 除非您创建一个临时变量来存储中间值 。

我唯一能想到的就是创建一个继承的控制器, 并添加您自己的事件和属性。 当即时提示时, 您的事件会弹出属性, 并在触发时拨打鼠标单击 。

使用标准事件模式。您可以检索事件源头,并将其投影到想要的类型。

this.Controls[btnAdd.Name].MouseClick += new MouseEventHandler(MyControl_MouseClick);

//...

void MyControl_MouseClick(object sender, MouseEventArgs e)
{
    var button = sender as Button;

    if (button.Name == "Add") // here is how to retrieve the button name
    {
        ...
    }
}

您不能这样做 。

代表语法之后是附加该特定事件的方法。您可以为该控制创建自定义控制和自定义事件。

在这里,我们如何创建事件如下:

  // Define a delegate named LogHandler, which will encapsulate
    // any method that takes a string as the parameter and returns no value
       public delegate void LogHandler(string message);

    // Define an Event based on the above Delegate
       public event LogHandler Log;

参考http://www.codeproject.com/articles/4773/Events-and-Delegates-simplified" rel=“nofolpolates”>Events和代表简化了

创建自定义控制时遵循此功能 - < a href=""http://blogs.msdn.com/b/jfoscoding/archive/2004/12/06/2755505.aspx" rel=“nofollow” > 在 Winforms 中创建自定义控制 - 第一部分 和 < a href=" http://msdn.microft.com/en-us/library/6hws6h2t.aspx" rel=“nofollow” > 以.NET Frameworm 开发自定义窗口格式控制 :

public partial class UserControl1 : TextBox

这项工作应:

this.Controls[btnAdd.Name].MouseClick += 
  (sender, e) => generalMethods.generatePopup(sender, e, i);

这将创建一种独特的匿名方法, 带有独特的参数, 由每个按键点击事件调用 。

您必须在内部范围中声明索引, 否则它仍然会引用您的循环参数 。

for (int i = 0; i < 42; i++)
{
    this.Controls[name].MouseClick += (sender, e) =>
    {
        int index = i;
        generalMethods.generatePopup(sender, e, index);
    }
}

您不需要为每个按钮指定一个处理器( 一个对所有人都有效), 但是您必须给每个按钮给它自己的索引对象 。





相关问题
Anyone feel like passing it forward?

I m the only developer in my company, and am getting along well as an autodidact, but I know I m missing out on the education one gets from working with and having code reviewed by more senior devs. ...

NSArray s, Primitive types and Boxing Oh My!

I m pretty new to the Objective-C world and I have a long history with .net/C# so naturally I m inclined to use my C# wits. Now here s the question: I feel really inclined to create some type of ...

C# Marshal / Pinvoke CBitmap?

I cannot figure out how to marshal a C++ CBitmap to a C# Bitmap or Image class. My import looks like this: [DllImport(@"test.dll", CharSet = CharSet.Unicode)] public static extern IntPtr ...

How to Use Ghostscript DLL to convert PDF to PDF/A

How to user GhostScript DLL to convert PDF to PDF/A. I know I kind of have to call the exported function of gsdll32.dll whose name is gsapi_init_with_args, but how do i pass the right arguments? BTW, ...

Linqy no matchy

Maybe it s something I m doing wrong. I m just learning Linq because I m bored. And so far so good. I made a little program and it basically just outputs all matches (foreach) into a label control. ...

热门标签