动态添加上下文菜单项异常:重复添加仍提示未包含该项
解决动态添加上下文菜单项的判断异常问题
这问题我太熟了!核心原因其实是你每次都在新建ToolStripMenuItem实例,导致Contains方法的判断完全失效,给你拆解下原因和解决方案:
问题根源
你每次执行代码时都会写ToolStripMenuItem Colour = new ToolStripMenuItem("Colour");,哪怕之前已经把同名菜单项加到ctmFile里了,这个新创建的实例和之前添加的那个是完全不同的对象。而ToolStripItemCollection.Contains()是通过对象引用是否相等来判断的,不是看文本或者其他属性,所以每次判断都会返回false,自然会出现“明明加过系统却说没有”的矛盾情况。
两种可行解决方案
方案1:复用同一个菜单项实例
把Colour菜单项的创建移到方法外部(比如作为类的成员变量),这样每次判断和操作都是同一个对象引用:
// 作为类的成员变量,只初始化一次 private ToolStripMenuItem _colourMenuItem = new ToolStripMenuItem("Colour"); // 上下文菜单显示的方法里 private void ShowFileContextMenu() { Selecteditem = lvFiles.FocusedItem.Text.ToString(); // 先调整菜单项,再显示菜单 if (lvFiles.FocusedItem.ImageKey.ToString() == "Folder") { if (!ctmFile.Items.Contains(_colourMenuItem)) { ctmFile.Items.Add(_colourMenuItem); } } else { if (ctmFile.Items.Contains(_colourMenuItem)) { ctmFile.Items.Remove(_colourMenuItem); } } ctmFile.Show(Cursor.Position); }
另外建议把Show方法放在菜单项调整之后,避免用户看到未更新的菜单内容。
方案2:通过菜单项属性查找已有项
如果不想提前保存实例,可以通过文本(或自定义Tag属性)查找已存在的菜单项:
private void ShowFileContextMenu() { Selecteditem = lvFiles.FocusedItem.Text.ToString(); // 通过文本查找已有菜单项 var colourItem = ctmFile.Items.Cast<ToolStripMenuItem>() .FirstOrDefault(item => item.Text == "Colour"); if (lvFiles.FocusedItem.ImageKey.ToString() == "Folder") { if (colourItem == null) { ctmFile.Items.Add(new ToolStripMenuItem("Colour")); } } else { if (colourItem != null) { ctmFile.Items.Remove(colourItem); } } ctmFile.Show(Cursor.Position); }
如果有重名菜单项的风险,建议给菜单项设置唯一的Tag值,用Tag来匹配会更可靠。
内容的提问来源于stack exchange,提问作者UniBandit
相关产品推荐
相关产品推荐

