Back to Devexpress

Create Custom Diagram Items

windowsforms-404797-controls-and-libraries-diagrams-diagram-items-create-custom-diagram-items.md

latest13.0 KB
Original Source

Create Custom Diagram Items

  • Feb 02, 2024
  • 7 minutes to read

Alongside a wide range of default diagram items (shapes, containers, connectors, and images), the DiagramControl offers multiple techniques to create custom or pre-configured items:

Pre-configure a Default Item and Register It in a New Stencil

The code example below does the following:

csharp
DiagramStencil myStencil = new DiagramStencil("myStencil", "Custom Items");
myStencil.RegisterTool(new FactoryItemTool(
    "customItem",
    () => "Custom Item",
    diagram => new DiagramImage() { Image = "img.png" },
    new Size(200, 30)
));
DiagramToolboxRegistrator.RegisterStencil(myStencil);
diagramControl1.SelectedStencils = new StencilCollection() { "myStencil" };
vb
Dim myStencil As DiagramStencil = New DiagramStencil("myStencil", "Custom Items")
myStencil.RegisterTool(New FactoryItemTool("customItem", Function() "Custom Item", Function(diagram) New DiagramImage() With {
    .Image = "img.png"
}, New Size(200, 30)))
DiagramToolboxRegistrator.RegisterStencil(myStencil)
Me.diagramControl1.SelectedStencils = New StencilCollection() From {"myStencil"}

View Example: Register FactoryItemTools for Regular and Custom Shapes

FactoryItemTool allows you to define a tool that creates diagram items on the canvas. You can display this tool in a DiagramStencil (Shapes Panel) or assign it to the DiagramOptionsBehavior.ActiveTool property. Underlying items can be the following objects or their descendants: DiagramShape, DiagramContainer, DiagramConnector, or DiagramImage.

Use FactoryItemTool in the following cases:

  • To create an additional tool that adds and pre-configures a default diagram item.
  • To create an additional tool that adds a diagram item descendant.

Note that you do not have to create and register new tools. Sometimes you may want to leave stencils and their item collections unchanged. You can still execute custom actions or modify settings when a user adds default items to the canvas. For this purpose, handle DiagramControl.ItemCreating and DiagramControl.ItemInitializing events.

Combine Multiple Shapes into One

You can use DiagramContainers with multiple inner shapes to create custom shapes. Use this technique if geometry of shapes may combine predefined shapes.

View Example: Create Custom Shapes Based on Diagram Containers

  1. Create a container and add static non-selectable shapes:

  2. Specify a FactoryItemTool that creates an instance of this container. Add this tool to a stencil:

Create Shapes Based on SVG Images

The DiagramControl allows you to use SVG images as shapes. The code sample below demonstrates a basic example of how you can set up such a custom diagram item. For complete code and additional details on this item type, its settings, and limitations, refer to the following article: SVG Shapes.

xml
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
     viewBox="0 0 100 100" style="enable-background:new 0 0 100 100;" xml:space="preserve">
    <circle cx="50" cy="50" r="40" stroke-width="4" stroke="blue" fill="green"/>
</svg>
csharp
void RegisterStencil() {
    var stencil = new DiagramStencil("CustomStencil", "SVG Shapes");

    System.IO.FileStream stream = System.IO.File.Open("..\\..\\greencircle.svg", System.IO.FileMode.Open);

    var shapeDescription = DevExpress.Diagram.Core.ShapeDescription.CreateSvgShape(
        shapeId: "SVGCircle",
        name: "SVG Circle",
        svgStream: stream,
        getConnectionPoints: (s) => new[] { new System.Windows.Point(s.Width / 2, s.Height / 2) }
    );

    stencil.RegisterShape(shapeDescription);
    DiagramToolboxRegistrator.RegisterStencil(stencil);

    diagramControl1.SelectedStencils = new StencilCollection() { "CustomStencil" };
}
vb
Private Sub RegisterStencil()
    Dim stencil = New DiagramStencil("CustomStencil", "SVG Shapes")

    Dim stream As System.IO.FileStream = System.IO.File.Open("..\..\greencircle.svg", System.IO.FileMode.Open)

    Dim shapeDescription = DevExpress.Diagram.Core.ShapeDescription.CreateSvgShape(
        shapeId:="SVGCircle", 
        name:="SVG Circle", 
        svgStream:=stream, 
        getConnectionPoints:=Function(s) {New System.Windows.Point(s.Width / 2, s.Height / 2)}
    )

    stencil.RegisterShape(shapeDescription)
    DiagramToolboxRegistrator.RegisterStencil(stencil)

    diagramControl1.SelectedStencils = New StencilCollection() From {
        "CustomStencil"
    }
End Sub

View Example: Register and Use SVG Shapes

Use Templates to Create Custom Shapes and Containers

ShapeTemplate and ContainerShapeTemplate classes allow you to define shapes and containers in XML and use them in the diagram. The code sample below demonstrates how to create a basic shape template. Refer to the following help topic for information on templates, available elements, and parameters: Use Templates to Create Custom Shapes and Containers.

xml
<Shapes xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <ShapeTemplate Id="MyEllipse" DefaultSize="120, 100">
        <Start X="0" Y="0.5"/>
        <Arc X="1" Y="0.5" Direction="Clockwise" Size="CreateSize(W/2,H/2)"/>
        <Arc X="0" Y="0.5" Direction="Clockwise" Size="CreateSize(W/2,H/2)"/>
    </ShapeTemplate>
</Shapes>
csharp
using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("WinDiagramSample.CustomShapes.xml")) {
    var stencil = DiagramStencil.Create(
        "CustomStencil",
        "Custom Shapes",
        stream,
        shapeName => shapeName
    );
    DiagramToolboxRegistrator.RegisterStencil(stencil);
}
diagramControl1.SelectedStencils = new StencilCollection() { "CustomStencil" };
vb
Using stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("WinDiagramSample.CustomShapes.xml")
    Dim stencil = DiagramStencil.Create("CustomStencil", "Custom Shapes", stream, Function(shapeName) shapeName)
    DiagramToolboxRegistrator.RegisterStencil(stencil)
End Using

diagramControl1.SelectedStencils = New StencilCollection() From {
    "CustomStencil"
}

View Example: Create Custom Shapes with Connection Points

Extend a Default Diagram Item

You can create diagram item descendants to extend default diagram items with additional properties. The code sample below demonstrates a basic example of such a custom diagram item. Refer to the following help topic for complete code, additional details, and limitations: Extend a Default Diagram Item.

csharp
public class CustomDiagramShape : DiagramShape {
    [XtraSerializableProperty]
    public string DatabaseObjectID { get; set; }
    static CustomDiagramShape() {
        DiagramControl.ItemTypeRegistrator.Register(typeof(CustomDiagramShape));
    }
}
vb
Public Class CustomDiagramShape
    Inherits DiagramShape

    <XtraSerializableProperty>
    Public Property DatabaseObjectID As String

    Shared Sub New()
        DiagramControl.ItemTypeRegistrator.Register(GetType(CustomDiagramShape))
    End Sub
End Class
csharp
void RegisterStencil() {
    var stencil = new DevExpress.Diagram.Core.DiagramStencil("CustomStencil", "Custom Shapes");
    var itemTool = new FactoryItemTool(
        "CustomShape",
        () => "Custom Shape", 
        diagram => {
            CustomDiagramShape customShape = new CustomDiagramShape() { Width = 100, Height = 50 };
            return customShape;
        },
        new Size(100, 50),
        false
    );
    stencil.RegisterTool(itemTool);
    DiagramToolboxRegistrator.RegisterStencil(stencil);
    DiagramControl.ItemTypeRegistrator.Register(typeof(CustomDiagramShape));
}

void diagramControl_CustomGetEditableItemProperties(object sender, DiagramCustomGetEditableItemPropertiesEventArgs e) {
    if (e.Item is CustomDiagramShape) {
        e.Properties.Add(TypeDescriptor.GetProperties(typeof(CustomDiagramShape))["DatabaseObjectID"]);
    }
}
vb
Private Sub RegisterStencil()
    Dim stencil = New DiagramStencil("CustomStencil", "Custom Shapes")
    Dim itemTool = New FactoryItemTool("CustomShape", Function() "Custom Shape", Function(diagram)
        Dim customShape As CustomDiagramShape = New CustomDiagramShape() With {.Width = 100, .Height = 50}
        Return customShape
    End Function, New Size(100, 50), False)
    stencil.RegisterTool(itemTool)
    DiagramToolboxRegistrator.RegisterStencil(stencil)
    DiagramControl.ItemTypeRegistrator.Register(GetType(CustomDiagramShape))
End Sub

Private Sub diagramControl_CustomGetEditableItemProperties(ByVal sender As Object, ByVal e As DiagramCustomGetEditableItemPropertiesEventArgs)
    If TypeOf e.Item Is CustomDiagramShape Then
        e.Properties.Add(TypeDescriptor.GetProperties(GetType(CustomDiagramShape))("DatabaseObjectID"))
    End If
End Sub

View Example: Create a DiagramShape Descendant with Editable and Serializable Properties

Examples