简体   繁体   中英

C# .net How do I remove a string item from a context menu strip

I am trying to remove the item with the string "Server List" from a context menu strip however the function Remove() doesn't take strings it takes "ToolStripItem value". I also tryed converting the Context menu strip to an array and list but those things didn't work either. Apologies if I'm being stupid but i'm a bit stuck.

This is my code

if (!MenuStrip.Items.ToString().Contains("Server List"))
{
    // it comes up with the error CS1503 and won't 
    // compile: cannot convert from string to System.Windows.Forms.ToolStripItem
    MenuStrip.Items.Remove("Server List");
} 

Without seeing the rest of your code, It feels like you are missing your MenuStrip declaration. Then, use the variable

    var menuStrip = new MenuStrip();
    // or  MunuStrip menuStrip = new MenuStrip();
    
    if (!menuStrip.Items.ToString().Contains("Server List"))
    {
        // it comes up with the error CS1503 and won't 
        // compile: cannot convert from string to System.Windows.Forms.ToolStripItem
        menuStrip.Items.Remove("Server List");
    }

Items is not a list of string it's a list of "ToolStripItem".

It means the second line (remove) will not compile.

It also mean the "if" will not work as expected since the ToString of a list will give you something like "System.Collections.Generic.List`1[System.Int32]" for a List<int> so you will never find a value in it.

Let's assume the value "Server List" is in the "Text" property here is the code:

if (menuStrip.Items.Any(i => i.Text == "Server List")) 
{
    menuStrip.Items.Remove(menuStrip.Items.First(i => i.Text == "Server List"));
}

That code will work but is not optimal because it will search the item containing "Server List" twice (once during the Any and once during the First).

Best option would be:

var serverListToolStripItem = menuStrip.Items.FirstOrDefault(i => i.Text == "Server List")
if (serverListToolStripItem != null) 
{
    menuStrip.Items.Remove(serverListToolStripItem);
}

The accepted answer from @arcord will usually work and in this case may never fail, but does contain a common mistake made in Linq statements. Use of.FirstOrDefault() is often used when.SingleOrDefault() is more correct. If there are two or more instances with a value of "Server List" only the first instance that is returned will be removed. Leaving the other instances present. That may or may not be the desired result. Using the.SingleOrDefault() will throw an exception that can be handled appropriately. Check this: LINQ: When to use SingleOrDefault vs. FirstOrDefault() with filtering criteria

Turns out I messed up before and now I have this solution for adding and removing items to the context menu strip.

List<string> items = new List<string>();
foreach (object obj in MenuStrip.Items)
{
    items.Add(obj.ToString());
}
// items.Add(string);
// items.Remove(string);

MenuStrip.Items.Clear();
foreach (string item in items)
{
    MenuStrip.Items.Add(item);
}

Also to work out which item was clicked you can create an event when a context menu item is clicked and then get the item

private void MenuStrip_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
{
    if (e.ClickedItem.ToString() == "Server List")
    {
        // code
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM