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

C# 如何最多启用一次菜单项?,c#,menuitem,isenabled,C#,Menuitem,Isenabled,仅当特定列表框中存在特定类型的文件时,才需要启用某些菜单项。该列表框中可能有大量条目,但即使只有一个条目属于所讨论的文件类型,也需要启用其菜单项。因此,我得到了以下代码: foreach (String pt in platypusTables) { if (pt.IndexOf("Duckbill") == 0) { menuItemSEND_Duckbills.Enabled = true; } if (pt.IndexOf("Platypus

仅当特定列表框中存在特定类型的文件时,才需要启用某些菜单项。该列表框中可能有大量条目,但即使只有一个条目属于所讨论的文件类型,也需要启用其菜单项。因此,我得到了以下代码:

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);
}

…但我怀疑这是否更有效,也许更有效。我是否被一次又一次可能启用的菜单项困住了,或者有没有解决这个难题的方法?

从某种意义上说,你被困住了,但这个任务并没有那么昂贵。
if
语句将不再有效,因为控件已经执行了该检查:

你可以做的一件事是设置旗帜,或者将它们放在一起。例如,假设您有8个选项,您可以设置二进制映射,以便:

Dictionary<String, byte> typeMapping = new Dictionary<String, byte>();
typeMapping.Add("FileType1", 0x01); //00000001
然后,您只需循环检查位标志集

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

    checkByte = checkByte >> 1;
}
这样,您只需真正检查enable并设置一次实际值。根据我的经验,这是一种梳理/检查大量标志的非常有效的方法。唯一的缺点是,一旦超过64个选项,就开始耗尽足够大的数据类型:(

你也许可以通过使用<代码> [FLAG]


但实际上,这很复杂,可能不值得它给你带来任何微不足道的好处。如果你没有好的评论(尤其是类型映射),那么它也很难阅读。只需分配!

从某种意义上说,您被卡住了,但分配并没有那么昂贵。
if
语句不会更有效,因为控件已经执行了该检查:

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

Dictionary<String, byte> typeMapping = new Dictionary<String, byte>();
typeMapping.Add("FileType1", 0x01); //00000001
然后,您只需循环检查位标志集

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

    checkByte = checkByte >> 1;
}
这样,您只需真正检查enable并设置一次实际值。根据我的经验,这是一种非常有效的方法来梳理/检查大量标志。唯一的缺点是,一旦您获得超过64个选项,您就开始耗尽足够大的数据类型:(

你也许可以通过使用<代码> [FLAG]


实际上,这很复杂,可能不值得它给你带来任何微不足道的好处。如果你没有好的评论(尤其是类型映射),那么阅读起来也很困难。只需分配就行了!

如果你只想启用项目(而不想禁用),你可以使用以下方法:

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;
     }
}

我希望这对您有所帮助

如果您只想启用项目(而不想禁用),您可以使用以下方法:

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;
     }
}

我希望这对您有所帮助

您可以扫描集合中以您要查找的每种类型开头的任何字符串。对
any()
的调用将在找到匹配项时停止,并且您最多启用一次每个菜单

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

listBoxWork.DataSource = platypusTables;

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

您可以扫描集合以查找的每种类型开头的任何字符串例如,
Any()
的调用将在找到匹配项时停止,并且您最多启用一次每个菜单

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

listBoxWork.DataSource = platypusTables;

我不确定这会有多高的性能,因为您要多次扫描同一个集合以查找每个字符串的第一个匹配项。我想这取决于字符串集合的大小,以及您以这种方式启用的菜单项的数量。

我喜欢这一个,因为它最容易理解。额外的枚举将非常有用,但这可能不重要。+1表示简单性/可读性。我喜欢这一个,因为它最容易理解。额外的枚举将很受欢迎,但可能不重要。+1表示简单性/可读性。