C# – Windows Forms right-click menu for multiple controls

cwinforms

I have several controls in a Windows Form and I want an identical menu to popup on each when right-clicked. However, the action should vary slightly based on which control was clicked.

The problem I'm having is that the ToolStripMenuItem doesn't have any information about which control was originally clicked to make the tool strip visible. I really don't want to need a separate context menu for each control!

Thus far my code looks something like:

private void InitializeComponent()
{
    this.openMenuItem = new ToolStripMenuItem();
    this.openMenuItem.Text = "Open";
    this.openMenuItem.Click += new EventHandler(this.openMenuItemClick);

    this.runMenuItem = new ToolStripMenuItem();
    this.runMenuItem.Text = "Run";
    this.runMenuItem.Click += new EventHandler(this.runMenuItemClick);

    this.contextMenuStrip = new ContextMenuStrip(this.components);
    this.contextMenuStrip.Items.AddRange(new ToolStripMenuItem[]{
        this.openMenuItem,
        this.runMenuItem});

    this.option1 = new Label();
    this.option1.Click += new EventHandler(this.optionClick);

    this.option2 = new Label();
    this.option2.Click += new EventHandler(this.optionClick);
}

void optionClick(object sender, EventArgs e)
{
    MouseEventArgs mea = e as MouseEventArgs;
    Control clicked = sender as Control;

    if(mea==null || clicked==null) return;

    if(mea.Button == MouseButtons.Right){
        this.contextMenuStrip.Show(clicked, mea.Location);
    }
}

void openMenuItemClick(object sender, EventArgs e)
{
    //Open stuff for option1 or option2, depending on which was right-clicked.
}

void runMenuItemClick(object sender, EventArgs e)
{
    //Run stuff for option1 or option2, depending on which was right-clicked.
}

Best Answer

Within runMenuItemClick you need to cast then sender to a ToolStripMenuItem and then cast its owner to a ContextMenuStrip. From there you can look at the ContextMenuStrip's SourceControl property to get the name of the control that clicked the item.

void runMenuItemClick(object sender, EventArgs e) {
    var tsItem = ( ToolStripMenuItem ) sender;
    var cms = ( ContextMenuStrip ) tsItem.Owner;
    Console.WriteLine ( cms.SourceControl.Name );
}
Related Topic