Creating a custom DSL Connector

Published 22 November 06 11:36 PM | mhatch 

While developing my architecture designer using the Domain Specfic Language tools in Visual Studio I wanted to create my own connector type with filled circles at the ends of the connector.  Many thanks to Bhavin B for his post on the Microsoft Forums for getting me started.  I'm going to recap the steps here for clarity since some of his instructions were not completely clear.

Connectors in the DSL tools come with default decorators that inclue arrows and diamonds, but not circles.  Decorators at the ends of the connector lines are drawn using a 2D GraphicsPath so that the drawing scales well in the designer.  The process for customizing the decorators involves creating the custom decorator class, and extending the Connector.InitializeInstanceResources to load the custom decorators in the call to SetDecorators.  The two first parameters for SetDecorators controls whether the custom decorator appears at one or both ends of the connector.

  1. Modify the ExampleConnector 'shape' (in the right-hand swim lane) to allow modifications by setting 'Generates Double Derived' = True.
  2. Transform templates so the partial classes are created.
  3. Add a new partial class to your project extending the Connector.InitializeInstanceResources to use your custom decorator as arguments (first arg is one end, second is the other end of the connector).

using DslModeling = global::Microsoft.VisualStudio.Modeling;
using DslDesign = global::Microsoft.VisualStudio.Modeling.Design;
using DslDiagrams = global::Microsoft.VisualStudio.Modeling.Diagrams;
using System.Drawing.Drawing2D;

namespace Company.Language1
{

public partial classExampleConnector : ExampleConnectorBase
{


protected override void InitializeInstanceResources()
{

base.InitializeInstanceResources();
this.SetDecorators(new DecoratorFilledCircle(), new DecoratorFilledCircle(), false);

}

}

}

4.  Create another new class, this time for the custom decorator.  This one doesn't have to be a partial class. Use the same 'using' statements as above. Subclass from LinkDecorator, and override the GetPath method to draw the custom decorator shape you desire.  Here I've used path.AddEllipse to draw a circle.  I also set the FillDecorator property to true so it will draw a filled circle rather than an open one.  I manually moved the ellipse x y parameters since it did not appear centered on the end of the connector.  There is a property for the line width of the connector that is set in the VS property inspector on the DslDefinition.Connector class called 'Thickness', but I'm not sure how to access it without modifying the parameters passed to GetPath.

namespace Company.Language1
{
public class DecoratorFilledCircle : DslDiagrams.LinkDecorator
{
protected override System.Drawing.Drawing2D.GraphicsPath GetPath(Microsoft.VisualStudio.Modeling.Diagrams.RectangleD bounds)
{
GraphicsPath path = DecoratorPath;

//Fill the circle

this.FillDecorator = true;

//Draw an ellipse, moving the top left to compensate for line width

//TODO: Figure out how to retrieve the line width programmatically. DslDefinition.Connector.Thickness

path.AddEllipse((float)(bounds.X + .01), (float)(bounds.Y + .01), (float)(bounds.Width * .8), (float)(bounds.Height * .8));

return path;

}
}

}

5. That about does it.  Make sure that your custom connector is mapped to the relationship in your DslDefinition.dsl and you should have custom decorators on your connector

Here is a sample of my custom connector.  Picture is kinda small, but you get the idea. You can see the filled circles on each end of the connector.  They are much more prevalent in the designer.

 

Comments

No Comments
Anonymous comments are disabled

Search

This Blog

Syndication

Page view tracker