How to Create a User Symbol That Acts as a Container

With ILOG Diagrammer for .NET, you can create user symbols very easily, and this is covered extensively in the user manual and this post, among others.

ILOG Diagrammer for .NET also provides several built-in container classes, for example the Canvas class, that is very useful to create composite graphic objects.

Something that you may need to do is to combine these two features, that is, create a user symbol that acts as a container. This is pretty easy to do, but there is no sample that shows it, so here we go. We will implement a very simple ContainerSymbol that looks like this:

containersymbol1.png

The ContainerSymbol is a simple rectangular symbol with a title, and it can contain children (two rectangles in the picture above).

As usual, we will use Visual Studio to build our symbol. It is made of a DockPanel that contains a title and a nested Canvas:

containersymbol2.png

Now, we need to add a bit of code to make sure that our symbol will accept children.

First, the symbol must have a property that will hold the collection of children.We will call this property SymbolChildren (not Children, because this is an existing property of the UserSymbol class):

        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        public Collection<GraphicObject> SymbolChildren
        {
            get { return canvas1.Objects; }
        }

As you can see the SymbolChildren property just returns the Objects property of the nested Canvas, so when a graphic object is added to the SymbolChildren collection, it will really be added to the nested Canvas. Note the DesignerSerializationVisibility attribute: it makes sure the collection’s contents will be serialized even though the property is read-only.

OK, now we can already add children to our symbol by writing code like this:

        containerSymbol.SymbolChildren.Add(new Rect(0, 0, 100, 100));

But we want our symbol to behave like a fully functional container, that is, we want to be able to drag-and-drop children into it when we use the Visual Studio designer. For this, let’s add this other piece of code:

        protected override GraphicContainer GetContainerForLogicalChildren()
        {
            return canvas1;
        }

This override tells the user symbol that it has a special element that will contain the “logical” children of the symbol, which means that the children will appear to be added to the symbol, whereas in fact they will be added to the nested Canvas.

Finally, one last piece of code is necessary to make sure that the children of the container symbol are correctly serialized in XML. For this, we need to define a custom designer for our symbol:

   [Designer(typeof(ParentSymbolDesigner))]
    public partial class ContainerSymbol : UserSymbol
    {
        ...
    public class ParentSymbolDesigner : UserSymbolDesigner
    {
        protected override PropertyDescriptor GetChildrenPropertyDescriptor()
        {
            return TypeDescriptor.GetProperties(Component)["SymbolChildren"];
        }
    }

The GetChildrenPropertyDescriptor virtual method tells ILOG Diagrammer for .NET which property to use to serialize the children of the container symbol.

We are done! Our container symbol acts as a basic container, you can add or remove children to it in the Visual Studio designer, select and move the children, etc.

Here is the full  source code of the sample.

Share and Enjoy: These icons link to social bookmarking sites where readers can share and discover new web pages.
  • Digg
  • del.icio.us
  • Netvouz
  • DZone
  • ThisNext
  • MisterWong
  • Wists

Tags: , ,

Leave a Reply