为什么 ToolStripMenuItem.Click 个事件处理程序显示相同的内容?

Why ToolStripMenuItem.Click event handlers show the same content?

我有一个树视图,其中有一个名为 "FTPServerListNode" 的节点。

"FTPServerListNode"有2个FTPServerNode,1个是"serverId1",另外1个是"serverId2"。

FTPServerListNode 和 FTPServerNode 都是从 TreeNode 扩展而来。

每个子节点都有一个 ToolStripMenuItem。

每个 ToolStripMenuItem 都有自己的点击事件处理程序。

这 2 个点击事件处理程序只显示节点名称。

但是,我发现两个事件处理程序显示相同的内容(即 "serverId2")。

这是我的源代码。

using System;
using System.Windows.Forms;

namespace ToolStripMenuItemTest
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            treeView1.Nodes.Add(new FtpServerListNode());
        }
    }
    internal class FtpServerNode : TreeNode
    {
        internal FtpServerNode(string serverDesc, string serverId)
        {
            this.Text = serverDesc;
            this.Name = serverId;
        }
    }
    internal class FtpServerListNode : TreeNode
    {
        internal FtpServerListNode()
        {
            FtpServerNode ftpServerNode = new FtpServerNode("serverDesc1", "serverId1");

            var nN= ftpServerNode.Name;
            ToolStripMenuItem removeServerToolStrip = new ToolStripMenuItem();
            removeServerToolStrip.Text = "Remove This FTP Server";
            removeServerToolStrip.Click += (sender, e) => MessageBox.Show(nN);
            ftpServerNode.ContextMenuStrip = new ContextMenuStrip();
            ftpServerNode.ContextMenuStrip.Items.Add(removeServerToolStrip);
            this.Nodes.Add(ftpServerNode);

            ftpServerNode = new FtpServerNode("serverDesc2", "serverId2");
            nN= ftpServerNode.Name;
            removeServerToolStrip = new ToolStripMenuItem();
            removeServerToolStrip.Text = "Remove This FTP Server";
            removeServerToolStrip.Click += (sender, e) => MessageBox.Show(nN);
            ftpServerNode.ContextMenuStrip = new ContextMenuStrip();
            ftpServerNode.ContextMenuStrip.Items.Add(removeServerToolStrip);
            this.Nodes.Add(ftpServerNode);
            this.Text = "Root Node";
            this.Expand();
        }
    }
}

我附上我的项目屏幕供您参考。

请将您的事件处理程序更改为

var mName = ftpServerNode.Name;
removeServerToolStrip.Click += (sender, e) => MessageBox.Show(mName);

您 运行 陷入修改闭包问题: https://www.jetbrains.com/help/resharper/AccessToModifiedClosure.html

经过多次试验,以下代码有效:

internal class FtpServerListNode : TreeNode
{
    internal FtpServerListNode()
    {
        SortedDictionary<string, FtpServerNode> ftpServerList = new SortedDictionary<string, FtpServerNode>();
        FtpServerNode ftpServerNode = new FtpServerNode("serverDesc1", "serverId1");
        ftpServerList.Add("serverId1", ftpServerNode);
        ftpServerNode = new FtpServerNode("serverDesc2", "serverId2");
        ftpServerList.Add("serverId2", ftpServerNode);

        foreach (FtpServerNode fn in ftpServerList.Values)
        {
            ToolStripMenuItem removeServerToolStrip = new ToolStripMenuItem();

            removeServerToolStrip.Text = "Remove This FTP Server " + fn.Name;
            removeServerToolStrip.Click += (sender, e) => MessageBox.Show(fn.Name);
            fn.ContextMenuStrip = new ContextMenuStrip();
            fn.ContextMenuStrip.Items.Add(removeServerToolStrip);
            this.Nodes.Add(fn);
        }
        this.Text = "Root Node";
        this.Expand();
    }
}