如何最多启用菜单项一次?

时间:2015-01-15 00:40:18

标签: c# menuitem isenabled

只有在特定列表框中存在特定类型的文件时,才需要启用某些菜单项。该列表框中可能有大量条目,但即使只有一个是有问题的文件类型,也需要启用其菜单项。所以,我有以下代码:

foreach (String pt in platypusTables)
{
    if (pt.IndexOf("Duckbill") == 0)
    {
        menuItemSEND_Duckbills.Enabled = true;
    }
    if (pt.IndexOf("Platypus") == 0)
    {
        menuItemSEND_Platypi.Enabled = true;
    }
    listBoxWork.Items.Add(pt);
}

问题是菜单项可能会被启用数百次。我更喜欢只设置一次和一次的优雅,但无法找到一种合理的方法来实现这一点。我能做到这一点:

foreach (String pt in platypusTables)
{
    if ((pt.IndexOf("Duckbill") == 0) && (!(menuItemSEND_Duckbills.Enabled)))
    {
        menuItemSEND_Duckbills.Enabled = true;
    }
    if ((pt.IndexOf("Platypus") == 0) && (!(menuItemSEND_Platypi.Enabled)))
    {
        menuItemSEND_Platypi.Enabled = true;
    }
    listBoxWork.Items.Add(pt);
}

...但我怀疑这是否更高效,可能更少。我是否一次又一次地使用可能启用的菜单项,或者是否存在这个难题的解决方案?

3 个答案:

答案 0 :(得分:2)

您可以扫描集合中的任何字符串,从您要查找的每种类型开始。 Any()的来电会在找到匹配后停止,您最多只能启用一次菜单。

menuItemSEND_Duckbills.Enabled = platypusTables.Any(p => p.StartsWith("Duckbill"));
menuItemSEND_Platypi.Enabled = platypusTables.Any(p => p.StartsWith("Platypus"));

listBoxWork.DataSource = platypusTables;

我不确定这是多么高效,因为您为每个字符串的第一次出现多次扫描同一个集合。我想这取决于字符串集合的大小,以及您以这种方式启用的菜单项数量。

答案 1 :(得分:1)

从某种意义上说,你被困住了,但这项任务并不 昂贵。 if语句不会更有效,因为控件已经 检查:Reference Source

可以做的一件事是设置标志,并将它们组合在一起。例如,假设您有8个选项,则可以设置二进制映射:

Dictionary<String, byte> typeMapping = new Dictionary<String, byte>();
typeMapping.Add("FileType1", 0x01); //00000001

表示应该使用该文件类型打开最后一个选项。然后,你可以把你的清单:

byte finalTypes = 0x00;
foreach (string type in list.Select(f => f.FileType).Distinct())
    finalTypes |= typeMapping[type];

然后你只需要遍历 检查位标志集。

byte checkByte = 0x80;
while (checkByte != 0)
{
   if (finalTypes & checkByte != 0)
      //Bit set, enable

    checkByte = checkByte >> 1;
}

这样,你只需真的检查启用并设置实际值一次。根据我的经验,这是一种梳理/检查大量标志的非常有效的方法。唯一的缺点是,一旦你获得了超过64个选项,就会开始用尽足够大的数据类型:(。

可能能够使用[Flags] Enum做同样的事情,但我相信它受到类似的限制。如果您想沿着这条路走下去,还需要考虑一些事情。

但实际上,这很复杂,并且可能不值得可能给你的任何微不足道的收益。如果你没有好的评论(特别是类型映射),它也很难阅读。只需分配!

答案 2 :(得分:1)

如果您只想启用项目(并且永不禁用),您可以使用以下内容:

foreach (String pt in platypusTables)
{
    menuItemSEND_Duckbills.Enabled = menuItemSEND_Duckbills.Enabled || (pt.IndexOf("Duckbill") == 0);
    menuItemSEND_Platypi.Enabled = menuItemSEND_Platypi.Enabled || (pt.IndexOf("Platypus") == 0);
    listBoxWork.Items.Add(pt);
}

另一种方法可能是使用扩展方法:

foreach (String pt in platypusTables)
{
    menuItemSEND_Duckbills.EnableIfNot(pt,"Duckbill");
    menuItemSEND_Platypi.EnabledIfNot(pt,"Platypus");
    listBoxWork.Items.Add(pt);
}

//extention method, supposing a MenuItem class
public static void EnableIfNot(this MenuItem menuItem, string table, string nameToSearch)
{
     if(!menuItem.Enabled && table.IndexOf(nameToSearch)==0)
     {
             menuItem.Enabled=true;
     }
}

我希望这会有所帮助