I’ve answered this a couple of times internally, so I thought I’d better post it.
The Add… menus in DSL Designers are dynamically generated from the ElementMergeDirective data you supply as part of your model.
For example, if you say that a domain class Door can be merged in to a domain class House then we’ll dynamically generate an Add menu entry for Doors on Houses in the model explorer and on any compartment shape representation of House and Door.
This is handy, but our customization story here isn’t too hot as the only way you can get in and modify this is by finding the “Add” menu, zapping it completely and putting your own entries in there instead. This is pretty heavy handed as you’ll also have zapped the menu for “Add Chimney” and “Add RoseGarden” at the same time. See Duncan’s post here for how to accomplish this.
A sneaky way around this limitation is to take advantage of the fact that we call the CanMerge method on the parent as part of deciding whether to show individual menu items.
As it happens, we pass slightly odd parameters to this method when we’re calling it purely for the purposes of deciding whether to show a menu.
The signature for CanMerge looks like this (on the House class in our example)
protected override bool CanMerge(DslModeling::ProtoElementBase rootElement, DslModeling::ElementGroupPrototype elementGroupPrototype)
When you’re pasting or dragging prototypes from toolbox, the parameters contain “real” ProtoElements with real Ids.
However, when you’re testing the hypothetical ability to paste some not-yet-created future item from an add menu, the parameters contain “fake” ProtoElements with zero Ids.
So if rootElement.ElementId is Guid.Zero then you know you’re in a hypothetical test.
The menu building tests for both compartment and explorer are hypothetical , so if you return false on Guid.Zero, then the offending menu item should simply disappear from both places.
Not exactly blindingly obvious, but it’s gotten a couple of teams out of a hole.