C# 动态添加事件处理程序

25

你好,我有一个简单的问题。这是我的代码:

        XmlDocument xmlData = new XmlDocument();
        xmlData.Load("xml.xml");

        /* Load announcements first */
        XmlNodeList announcements = xmlData.GetElementsByTagName("announcement");

        for (int i = 0; i < announcements.Count; i++)
        {
            ToolStripMenuItem item = new ToolStripMenuItem();

            item.Name = announcements[i].FirstChild.InnerText;
            item.Text = announcements[i].FirstChild.InnerText;

            /* HERE IS WERE I NEED HELP */

            item.Click += new EventHandler();

            this.freedomMenu.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { item });
        }

xml的LastChild属性保存了每个公告的信息。我想创建一个点击事件处理程序,当单击列表项时,将显示一个带有其中数据的消息框。我的问题是我不知道如何动态生成事件处理程序来完成这个操作 :(

6个回答

44

尝试执行以下代码:

 /* HERE IS WERE I NEED HELP */

 item.Click += new EventHandler(toolStripClick);

实际处理程序:

void toolStripClick(object sender, EventArgs e)
{
     ToolStripItem item = (ToolStripItem)sender;
     MessageBox.Show(item.Text);
}    

我以为你想让LastChild在消息框中显示?那会显示FirstChild吗? - Steven Robbins
我不知道是否在想象,但我发现即使没有使用“new EventHandler”,也可以通过例如item.Click+=itemClick;来实现。我刚试着向一个窗体添加一个面板,并执行了panel.Click+=p_click;的想法,这个想法来自于wonky79在这里的回答:http://stackoverflow.com/questions/17047355/add-mouse-click-event-for-dynamically-created-panels - barlop
@barlop 确定你理解正确。可能当最初回答这个问题时,还没有这种添加事件处理程序的方式,或者我只是提供了常规的做法。item.Click += itemClick 是回答中表达式的语法糖。 - TheVillageIdiot

6
您可以使用ToolStripMenuItem的Tag属性:
item.Tag = Announcements[i].LastChild.InnerText;

public void item_click(object sender, EventArgs e)
{
    var menu = sender as ToolStripMenuItem;
    if (menu!= null)
        MessageBox.Show(menu.Tag);
}

或者你可以使用一个lambda表达式,它将捕获这个变量:

string data = Announcements[i].LastChild.InnerText;
item.Click += (s, e) => { MessageBox.Show(data); };

我发现使用Lambda非常有帮助,这正是我正在寻找的,不需要创建另一个方法,只需一行代码解决问题。 - Tanner Ornelas

2

如果我理解您的问题正确,您的“需要帮助”部分应该变成这样:

item.Click += new EventHandler(item_click);

那么您只需要在您的类中添加一个函数:
public void item_click(object sender, EventArgs e)
{
   //do stuff here
}

是的,但这就是我卡住的地方。我该如何将XML LastChild中的数据发送到该函数? - Tony
啊,我没有意识到这一点 - 虽然你已经可以看到答案已经给出 - 当你创建一个事件处理程序时,生成事件的对象(或在这种情况下被点击的对象)就是sender参数。通常,你只需要将其转换为正确的数据类型,然后继续进行。 - Streklin

2

你是在询问点击事件的签名吗?如果你正在使用Visual Studio,你应该能够输入

item.Click+= tab tab

它会自动生成一些内容。


1

对于现在遇到这个问题的人:

我只需要这样做:

public Form1() {
item.Click += item_Click;
}

private void item_Click(object sender, EventArgs e) {
// Code in here
}

不过,Visual Studio可以为您省去这些麻烦。当您键入 item.Click += 时,按下Tab键后它会自动填充。

Example


0
我建议您研究事件订阅。在事件中,您必须确保它是菜单项中的最后一项。
查看MSDN的帮助文档

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接