ToolStripMenuItem添加到多个位置

本文关键字:位置 添加 ToolStripMenuItem | 更新日期: 2023-09-27 17:58:49

我有一个很大的实体列表,用户需要能够从中进行选择。我的窗口上有一个ContextMenuStrip,每个实体类别都有几个MenuItems。

在一个图书馆的例子中,想想"职员"、"借阅者"、"赞助人"等等

"员工"可以包含"按就业类型"->{"全职"、"兼职"}或"按性别"->{{"男性"、"女性"}等

"可借文件"可能包含"按类型"->{"书籍"、"杂志"、"DVD"}或"按流派"->{"小说"->{"科幻"、"浪漫"、"犯罪"}、"非小说"{"科学"、"音乐"、"历史"}等

基本上,一个实体可以同时位于多个位置。工作人员可以是全职的,也可以是女性。一本可借的书可能是一本书,也可能是一部言情小说。等

我已经用程序创建了一个List<ToolStripMenuItem>以及事件处理程序、标记等等。然后,我用程序的方式浏览了它们中的每一个,并将它们添加到各种菜单和子菜单中,这样就可以从各种地方访问它们。其想法是,每个ToolStripMenuItem在内存中只需要一个对象,如果选中/未选中,则应该反映在所有对象上。

这似乎是一个优雅的解决方案,我真的很期待看到它的工作,但很明显,当我向一个ToolStripMenuItemDropDownItems添加一个ToolStripMenuItem时,它会从其他添加它的地方被删除。

这让我很难过。如果它们都是同一个对象,我就不必写很多代码来遍历并在选中一个项目时检查所有匹配的项目,因为选中一个会选中所有项目,而取消选中一个则会取消选中所有项目。

有没有其他方法可以用最少的代码实现这一点?

这是我的一个小例子:

foreach (ToolStripMenuItem item in staffItems)
{
  Staff s = (Staff)item.Tag;
  foreach (ToolStripMenuItem tsmi in byStaffLocationToolStripMenuItem.DropDownItems)
    if ((Location)tsmi.Tag == s.Location)
      tsmi.DropDownItems.Add(item); // [1] Item added here
  foreach (ToolStripMenuItem tsmi in byStaffTypeToolStripMenuItem.DropDownItems)
    if ((StaffType)tsmi.Tag == s.StaffType)
      tsmi.DropDownItems.Add(item); // removed from [1] and added here instead :(
}

ToolStripMenuItem添加到多个位置

这是ControlCollection的特性。从Control派生的任何对象同时只能在一个ControlCollection中。

如果你想遵循你的方法,我建议(草案)为你的命令引入抽象:

public interface ICommand
{
    string Name {get;set;}
    bool Enabled { get; set; }
    bool Checked { get; set; }
    void OnClick();
}

然后,您可以创建自己的类,该类将从ToolStripMenuItem派生,并将ICommand作为参数并使用它OnClick。现在,您应该能够为单个命令定义实现ICommand的单个对象。