Custom drop target

The automatically generated designer in DSL assumes that you have to put the shape on the surface and then eventually connect to others.

Statements, in microbasic, are executed sequentially so I want the designer to attach my shapes to one previously placed, dropping it in the link between two shapes.

To drive the shapes drop behaviour I have to modify where the shapes are allowed to be dropped.

Setting the attribute UsesCustomAccept does this (or at least I hope!!!).

<?xml version="1.0" encoding="utf-8"?>
<Dsl dslVersion="1.0.0.0" Id="bd36672a-93b9-4dce-82f8-2551432eb244" Description="Description for myns.Language1.Language1" ...>
  <Classes>
    <DomainClass Id="3a3a6bfd-90ef-4418-91a7-3792d2201167" Description="The root in which all other elements are embedded. Appears as a diagram." ....>
      <ElementMergeDirectives>
        <ElementMergeDirective UsesCustomAccept="true">
          <Notes>Creates an embedding link when an element is dropped onto a model. </Notes>
          <Index>
            <DomainClassMoniker Name="ExampleElement" />
          </Index>
          <LinkCreationPaths>
            <DomainPath>ExampleModelHasElements.Elements</DomainPath>
          </LinkCreationPaths>
        </ElementMergeDirective>
      </ElementMergeDirectives>
    </DomainClass>

As usual regenerate the templates and recompile.

An error appears...

Error    1    'myns.Language1.ExampleModel' does not contain a definition for 'CanMergeExampleElement' and no extension method 'CanMergeExampleElement' accepting a first argument of type 'myns.Language1.ExampleModel' could be found

Clicking on the error you are taken to the  call to the method that you have to implement. Using vs is easy to do this..hover your mouse to the little rectangle at the beginning of the method name.

 

CanMerge

Copy the generated method stub to your partial class and implement it.

How? I don't know...Stay tuned...

Double derived pattern in DSL

Customizing a DSL needs different expertise based on the amount of customization that you want to apply.

A 'basic' concept that you need to understand is the double derived pattern.

The DSL engine generates classes based on the dsl definition. Those classes are partial class so, like in asp.net or winform, you can create your code for the same class in another file separating it from the automatically generated.

Those classes are split in two separate files, but is essentially the same class so you can't replace a method automatically generated.

To address this problem the DSL framework introduce the double derived pattern. For each class (with the "Generates Double Derived" attribute set) the generated code is set on the base class so you are free to override the automatically generated code in the derived class.

If you have a class named ExampleElement (the one automatically generated if you create a new MinimalLanguage project) and you mark it with "Generates Double Derived" you'll get the following class structure

DoubleDerive

 

The framework generates an ExampleElementBase class that contains all the generated code, in the derived class (ExampleElement) you are free to override everything (except the constructor see below).

In case of the Sources property you'll write

public partial class ExampleElement
{
    public override Microsoft.VisualStudio.Modeling.LinkedElementCollection<ExampleElement> Sources
    {
        get
        {
            return base.Sources;
        }
    }
}          

The case of constructor it's a little bit different....the problem is that DSL tools must generate the constructor for the derived class (if not the framework couldn't instantiate the class). So if you need to override also the constructor you can set the "Has custom constructor".

(Remember to select "Transform all templates" and rebuild!)

In this case a compilation error is generated stating that you have to implement the constructor. Something like

Error    1    "...ExampleElement' does not contain a constructor that takes '0' arguments 

del.icio.us Tags:
«maggio»
domlunmarmergiovensab
27282930123
45678910
11121314151617
18192021222324
25262728293031
1234567