【问题标题】:Why ToolStripMenuItem.Click event handlers show the same content?为什么 ToolStripMenuItem.Click 事件处理程序显示相同的内容?
【发布时间】:2019-05-08 08:27:42
【问题描述】:

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

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

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

每个子节点都有一个 ToolStripMenuItem。

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

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

但是,我发现两个事件处理程序显示相同的内容(即“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();
        }
    }
}

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

【问题讨论】:

标签: c# eventhandler


【解决方案1】:

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

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

您遇到了修改后的闭包问题: https://www.jetbrains.com/help/resharper/AccessToModifiedClosure.html

【讨论】:

  • 它不起作用。我已更新问题详情。
  • 我用更具体的解决方案和解释更新了我的答案。
  • 还是不行,我已经更新了我的代码供大家参考。我正在使用 Visual Studio Community 2015 版。
  • 请使用nN1和nN2,否则同样的问题!您应该避免在两个 lambda 表达式中使用相同的变量。这就是问题所在。
【解决方案2】:

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-29
    • 2021-08-03
    • 2022-08-09
    • 2011-03-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多