Customizing and Extending a Domain-Specific Language

Note

This article applies to Visual Studio 2015. If you're looking for Visual Studio 2017 documentation, use the version selector at the top left. We recommend upgrading to Visual Studio 2017. Download it here.

Visual Studio Modeling and Visualization SDK (VMSDK) provides several levels at which you can define modeling tools:

  1. Define a domain-specific language (DSL) using the DSL Definition diagram. You can quickly create a DSL with a diagrammatic notation, a readable XML form, and the basic tools that are required to generate code and other artifacts.

    For more information, see How to Define a Domain-Specific Language.

  2. Fine-tune the DSL by using more advanced features of the DSL Definition. For example, you can make additional links appear when the user creates an element. These techniques are mostly achieved in the DSL Definition, and some require a few lines of program code.

  3. Extend your modeling tools by using program code. VMSDK is designed specifically to make it easy to integrate your extensions with the code that is generated from the DSL Definition. For more information, see Writing Code to Customise a Domain-Specific Language.

Note

When you have updated the DSL Definitions file, do not forget to click Transform All Templates in the toolbar of Solution Explorer before rebuilding your solution.

In this Section

To achieve this effect Refer to this topic
Allow the user to set the color and style properties of a shape. Right-click the shape or connector class, point to Add Exposed, and click an item.

See Customizing Presentation on the Diagram.
Different classes of model element look similar on the diagram, sharing properties such as initial height and width, color, tooltips. Use inheritance between shapes or connector classes. Mappings between derived shapes and derived domain classes inherit the mapping details of the parents.

Or, map different domain classes to the same shape class.
A class of model element is displayed by different shapes contexts. Map more than one shape class to the same domain class. When you build the solution, follow the error report and provide the requested code to decide what shape to use.
Shape color or other features such as font indicate current state. See Updating Shapes and Connectors to Reflect the Model.

Create a rule that updates the exposed properties. See Rules Propagate Changes Within the Model.

Or, use OnAssociatedPropertyChanged() to update non-exposed features such as link arrows or font.
Icon on shape changes to indicate state. Set the visibility of the decorator mapping in the DSL Details window. Locate several image decorators on the same position. See Updating Shapes and Connectors to Reflect the Model.

Or, override ImageField.GetDisplayImage(). See example in ImageField.
Set a background image on any shape Override InitializeInstanceResources() to add an anchored ImageField. See Customizing Presentation on the Diagram.
Nest shapes to any depth Set up a recursive embedding tree. Define BoundsRules to contain the shapes. See Customizing Presentation on the Diagram.
Attach connectors at fixed points on an element’s boundary. Define embedded terminal elements, represented by small ports on the diagram. Use BoundsRules to fix the ports in place. See the Circuit Diagram sample at Visualization and Modeling SDK.
Text field displays a value derived from other values. Map the text decorator to a Calculated or Custom Storage domain property. For more information, see Calculated and Custom Storage Properties.
Propagate changes between model elements, or between shapes See Validation in a Domain-Specific Language.
Propagate changes to resources such as other Visual Studio extensions outside the store. See Event Handlers Propagate Changes Outside the Model.
Property window displays properties of a related element. Set up Property Forwarding. See Customizing the Properties Window.
Property categories The properties window is divided into sections called categories. Set the Category of your domain properties. Properties with the same category name will appear in the same section. You can also set the Category of a relationship role.
Control user access to domain properties Set Is Browsable false to prevent a domain property from appearing in the Properties window at run time. You can still map it to text decorators.

Is UI Read Only prevents users from changing a domain property.

Program access to the domain property is not affected.
Change the name, icon, and visibility of nodes in your DSL’s model explorer. See Customizing the Model Explorer.
Enable copy, cut and paste Set the Enable Copy Paste property of the Editor node in DSL Explorer.
Copy reference links and their targets whenever an element is copied. For example, copy Comments attached to an item. Set the Propagates Copy property of the source role (represented by the line at one side of the domain relationship in the DSL Definition diagram).

Write code to override ProcessOnCopy to achieve more complex effects.

See Customizing Copy Behavior.
Delete, reparent, or relink related elements when an element is deleted. Set the Propagates Delete value of a relationship role. For more complex effects, override ShouldVisitRelationship and ShouldVisitRolePlayer methods in the MyDslDeleteClosure class, defined in DomainModel.cs

See Customizing Deletion Behavior
Preserve shape layout and appearance on copy and drag-drop. Add the shapes and connectors to the copied ElementGroupPrototype. The most convenient method to override is ElementOperations.CreateElementGroupPrototype()

See Customizing Copy Behavior.
Paste shapes in a chosen location, such as the current cursor position. Override ClipboardCommandSet.ProcessOnCopy() to use the location-specific version of ElementOperations.Merge(). See Customizing Copy Behavior.
Create additional links on paste Override ClipboardCommandSet.ProcessOnPasteCommand()
Enable drag and drop from this diagram, other DSLs or UML diagrams and Windows elements See How to: Add a Drag-and-Drop Handler
Allow a shape or tool to be dragged onto a child shape, such as a port, as if it were dragged onto the parent. Define an Element Merge Directive on the target object class, to forward the dropped object to the parent. See Customizing Element Creation and Movement.
Allow a shape or tool to be dragged onto a shape and have additional links or objects created. For example, to allow a comment to be dropped onto an item to which it is to be linked. Define an Element Merge Directive on the target domain class, and define the links to be generated. In complex cases, you can add custom code. See Customizing Element Creation and Movement.
Create a group of elements with one tool. For example, a component with a fixed set of ports. Override the toolbox initialization method in ToolboxHelper.cs. Create an Element Group Prototype (EGP) containing the elements and their relationship links. See Customizing Tools and the Toolbox.

Either include the principal and port shapes in the EGP, or define BoundsRules to position the port shapes when the EGP is instantiated. See BoundsRules Constrain Shape Location and Size.
Use one connection tool to instantiate several types of relationship. Add Link Connect Directives (LCD) to the Connection Builder that is invoked by the tool. The LCDs determine the type of the relationship from the types of the two elements. To make this depend on the states of the elements, you can add custom code. See Customizing Tools and the Toolbox.
Sticky tools – the user can double-click any tool to create many shapes or connectors in succession. In DSL Explorer, select the Editor node. In the Properties window, set Uses Sticky Toolbox Items.
Define menu commands See How to: Modify a Standard Menu Command
Constrain the model with validation rules See Validation in a Domain-Specific Language
Generate code, configuration files, or documents from a DSL. Generating Code from a Domain-Specific Language
Customize how models are saved to file. See Customizing File Storage and XML Serialization
Save models to databases or other media. Override YourLanguageDocData

See Customizing File Storage and XML Serialization
Integrate several DSLs so that they work as part of one application. See Integrating Models by using Visual Studio Modelbus.
Allow your DSL to be extended by third parties, and control the extension. Extend your DSL by using MEF

Sharing Classes between DSLs by using a DSL Library

Defining a Locking Policy to Create Read-Only Segments

See Also

How to Define a Domain-Specific Language
Writing Code to Customise a Domain-Specific Language
Modeling SDK for Visual Studio - Domain-Specific Languages