When I need to copy menu items in WPF I use the command pattern as suggested, but with some clever trickery you can still support event handlers as well (see more below). The code I use to copy items looks something like this, where "item" is the old MenuItem I am copying:
MenuItem copy = new MenuItem();
copy.Header = item.Header;
copy.Icon = item.Icon;
copy.Command = item.Command;
copy.CommandParameter = item.CommandParameter;
foreach( CommandBinding binding in item.CommandBindings ) {
copy.CommandBindings.Add( binding );
}
newCollection.Add( copy );
Obviously you might need to tweak which properties you copy depending on which features of the MenuItem you tend to use. I pretty much stick to Header, Icon, and Command so that's all I implemented.
Now, if you need to support event handler-style, you will need some sort of construction abstraction because you can only "play" with it before assigning to the event. Once you've added the event handler to the menu item it's pretty un-retrievable. If you have an actual RoutedEventHandler object though (pre-subscription), you can do this little work-around (where "handler" is the RoutedEventHandler instance I am wrapping):
ExecutedRoutedEventHandler executed = (sender, args) =>
{
RoutedEventArgs innerArgs = new RoutedEventArgs();
// The consumer probably shouldn't rely on these, but we'll copy them for completeness sake
innerArgs.RoutedEvent = args.RoutedEvent;
innerArgs.Handled = args.Handled;
innerArgs.Source = args.Source;
handler.Invoke( sender, innerArgs );
};
RoutedUICommand cmd = new RoutedUICommand( "Temp", "Temp", this.GetType() );
newItem.CommandBindings.Add( new CommandBinding(cmd, executed) );
newItem.Command = cmd;
You might need to replace
this.GetType()
with something else depending on the context in which you are constructing the menu items. I think it needs to be the type of the object that is going to be the ultimate parent of the MenuItem in the visual tree (in my case the object whose context menu items I am copying).