Search code examples
c#.nettoolstripsubmenucontextmenustrip

How to return the name of a ToolStripMenuItem inside of a sub menu in a ContextMenuStrip in .Net


My question might be ambiguous but here is my situation :

I have a square array of pictureboxes on my form, each has a handler to open the ContextMenuStrip whose content is generated based on a directory. Each folder in the directory will create a ToolStripMenuItem and each files inside that folder will be represented inside the DropDownItems of said menu menu item. Upon clicking on a sub item of my menu the picturebox's image will change based on what menu item was clicked.

My problem arises when I try to find out which sub item was clicked. How can I find that out with the _Clicked event of the ContextMenuStrip ? Here is my attempt so far :

        private void mstChooseTile_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
    {
        ContextMenuStrip s = (ContextMenuStrip)sender;
        ToolStripMenuItem x = (ToolStripMenuItem)e.ClickedItem;
        // Test to see if I can get the name
        MessageBox.Show(x.DropDownItems[1].Name);
        // Nope :(
    }

Solution

  • The ItemClicked event isn't going to work for you:

    A) It only works for immediate children.

    B) It fires even when clicking non-leaf nodes.

    Try subscribing to each ToolStripMenuItem instead. Here I skip subscribing to non-leaf nodes.

    using System;
    using System.Windows.Forms;
    
    public class Form1 : Form
    {
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1());
        }
    
        public Form1()
        {
            ContextMenuStrip = new ContextMenuStrip
            {
                Items =
                {
                    new ToolStripMenuItem
                    {
                        Text = "One",
                        DropDownItems =
                        {
                            new ToolStripMenuItem { Text = "One.1" },
                            new ToolStripMenuItem { Text = "One.2" },
                            new ToolStripMenuItem { Text = "One.3" },
                            new ToolStripMenuItem { Text = "One.4" },
                        },
                    },
                    new ToolStripMenuItem
                    {
                        Text = "Two",
                    },
                    new ToolStripMenuItem
                    {
                        Text = "Three",
                        DropDownItems =
                        {
                            new ToolStripMenuItem { Text = "Three.1" },
                            new ToolStripMenuItem { Text = "Three.2" },
                        },
                    },
                }
            };
    
            foreach (ToolStripMenuItem item in ContextMenuStrip.Items)
                Subscribe(item, ContextMenu_Click);
        }
    
        private static void Subscribe(ToolStripMenuItem item, EventHandler eventHandler)
        {
            // If leaf, add click handler
            if (item.DropDownItems.Count == 0)
                item.Click += eventHandler;
            // Otherwise recursively subscribe
            else foreach (ToolStripMenuItem subItem in item.DropDownItems)
                Subscribe(subItem, eventHandler);
        }
    
        void ContextMenu_Click(object sender, EventArgs e)
        {
            MessageBox.Show((sender as ToolStripMenuItem).Text, "The button clicked is:");
        }
    }