【问题标题】:ToolStripMenuItem added to several places?ToolStripMenuItem 加到几个地方?
【发布时间】:2011-09-10 15:12:00
【问题描述】:

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

在图书馆示例中,想想“员工”、“可借书”、“赞助人”等...

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

“Borrowables”可能包含“By Type” -> { “Books”、“Magazines”、“DVDs”} 或“By Genre” -> { “Fiction” -> { “Sci-Fi”、“Romance” 、“犯罪”}、“非小说”{“科学”、“音乐”、“历史”} } 等

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

我以编程方式创建了一个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 :(
}

【问题讨论】:

    标签: c# winforms contextmenustrip toolstripmenu


    【解决方案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 的单个对象了。

    【讨论】:

      猜你喜欢
      • 2013-11-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-16
      • 2012-01-08
      相关资源
      最近更新 更多