只有在特定列表框中存在特定类型的文件时,才需要启用某些菜单项。该列表框中可能有大量条目,但即使只有一个是有问题的文件类型,也需要启用其菜单项。所以,我有以下代码:
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);
}
...但我怀疑这是否更高效,可能更少。我是否一次又一次地使用可能启用的菜单项,或者是否存在这个难题的解决方案?
答案 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;
}
}
我希望这会有所帮助