3

我有大量的实体,用户需要从中进行选择。我的窗口上有一个 ContextMenuStrip,每个实体类别都有几个 MenuItem。

在图书馆的例子中,想想“职员”、“可借书”、“顾客”等……

“员工”可能包含“按雇佣类型”-> {“全职”、“兼职”} 或“按性别”-> {“男性”、“女性”} 等。

“Borrowables”可能包含“按类型”-> {“书籍”、“杂志”、“DVD”} 或“按类型”-> {“小说”-> {“科幻”、“浪漫”、“犯罪” " }、"非小说" { "科学"、"音乐"、"历史" } } 等。

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

我以编程方式创建了一个List<ToolStripMenuItem>带有事件处理程序、标签和一切的东西。然后我以编程方式浏览了它们中的每一个,并将它们添加到各种菜单和子菜单中,以便可以从不同的地方访问它们。这个想法是每个 ToolStripMenuItem 只需要 1 个内存对象,如果选中/取消选中它,那么应该反映在所有对象上。

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

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

有没有其他方法可以用最少的代码完成这个?

这是我所拥有的一个小例子:

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 :(
}
4

1 回答 1

1

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

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

public interface ICommand
{
    string Name {get;set;}
    bool Enabled { get; set; }
    bool Checked { get; set; }

    void OnClick();
}

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

于 2011-06-17T21:18:31.947 回答