ewhoambra
ewhoambra

Reputation: 100

C# - Duplicate ContextMenuStrip Items into another

I have two ContextMenuStrip(s) in a Windows Form Application, one of them has 3 items and the other one has none.

Let's suppose this:

ContextMenuStrip c1 = new ContextMenuStrip();
ContextMenuStrip c2;

c1 has 3 ToolStripMenuItems, c2 is the ContextMenuStrip destination where c1 items should be duplicated.

I tried to write this:

c2 = new ContextMenuStrip(c1.Container);

but it gives me an ArgumentNullException because c1.Container is Equal to null.

I cant figure out how to solve this, can you help me?

Ps. I would new ToolStripMenuItem(s), no references

and

while or foreach loops solutions are not the best way to do this.

Thank you :)

Upvotes: 1

Views: 2221

Answers (3)

Irvingz
Irvingz

Reputation: 119

Late to the party, but I have had the same issue in the past and found a reasonably simple solution.

Say your toolStripMenuItem is declared as 'TSMI_open' in a context menu, you can effectively hot-swap it between context menus as they open. Something like this:

void Context1_Opening(object sender, CancelEventArgs e)
{
     Context1.Items.Insert(0, TSMI_open);
}

void Context2_Opening(object sender, CancelEventArgs e)
{
     Context2.Items.Insert(0, TSMI_open);
}

The menu item will appear on both menus when seamlessly, and will cause no errors if the same menu is opened twice consecutively.

Upvotes: 1

Slai
Slai

Reputation: 22876

Then, have a function that creates the ContextMenuStrip and call it each time a new menu is needed

Func<ContextMenuStrip> newContextMenuStrip = () => { 
    var c = new ContextMenuStrip();
    c.Items.Add("item 1");
    c.Items.Add("item 2");
    c.Items.Add("item 3");
    return c;
};

var c1 = newContextMenuStrip();
var c2 = newContextMenuStrip();

Upvotes: 1

Ren&#233; Vogt
Ren&#233; Vogt

Reputation: 43886

You need to create a new ContextMenuStrip and add the Items (not the Container of c1 to the new menu:

c2 = new ContextMenuStrip();
c2.Items.AddRange(c1.Items);

But note that this does not duplicate the items. The same item instances are now in both menus.

If you want to clone them, this is rather complicated as you have to take care of the specific types of the items, the properties you want to clone and especially the event handlers.

A simple example could be:

c2.Items.AddRange(c1.Items.OfType<ToolStripItem>()
                           .Select(item => new ToolStripMenuItem(item.Text))
                           .OfType<ToolStripItem>().ToArray());

The second OfType is necessary to avoid a co-variant array conversion from ToolStripMenuItem[] to ToolStripItem[] which is expected by AddRange().


And a side note: Container is the component that contains the menu (thatswhy it's null when the menu is not shown) and not the thing the menu keeps its items in.

Upvotes: 0

Related Questions