Create Custom Diagram Items
- 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
- Combine Multiple Shapes into One
- Create Shapes Based on SVG Images
- Use Templates to Create Custom Shapes and Containers
- Extend a Default Diagram Item
Pre-configure a Default Item and Register It in a New Stencil
The code example below does the following:
- Creates an image item (DiagramImage). Specifies item dimensions and loads a predefined image.
- Wraps the pre-configured item into a tool (FactoryItemTool).
- Extends the Shapes Panel with a new group (DiagramStencil). Adds the new tool into the new stencil.
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" };
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.
Create a container and add static non-selectable shapes:
public DiagramContainer CreateContainerShape1() { var container = new DiagramContainer(); container.Appearance.BorderSize = 0; container.Appearance.BackColor = Color.Transparent; var innerShape1 = new DiagramShape() { CanSelect = false, CanChangeParent = false, CanEdit = false, CanCopyWithoutParent = false, CanDeleteWithoutParent = false, CanMove = false, Shape = BasicShapes.Trapezoid, Anchors = Sides.Top | Sides.Left | Sides.Right, Height = 50, Width = 200, Content = "Custom text" }; var innerShape2 = new DiagramShape() { CanSelect = false, CanChangeParent = false, CanEdit = false, CanCopyWithoutParent = false, CanDeleteWithoutParent = false, CanMove = false, Shape = BasicShapes.Rectangle, Anchors = Sides.All, Height = 150, Width = 200, Position = new DevExpress.Utils.PointFloat(0, 50), }; container.Items.Add(innerShape1); container.Items.Add(innerShape2); return container; }
Specify a FactoryItemTool that creates an instance of this container. Add this tool to a stencil:
void RegisterStencil() { var stencil = new DiagramStencil("CustomStencil", "Custom Shapes"); var itemTool = new FactoryItemTool( "CustomShape1", () => "Custom Shape 1", diagram => CreateContainerShape1(), new System.Windows.Size(200, 200), false ); stencil.RegisterTool(itemTool); DiagramToolboxRegistrator.RegisterStencil(stencil); diagramControl1.SelectedStencils = new StencilCollection() { "CustomStencil" }; }
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.
<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>
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" };
}
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.
<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>
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" };
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.
public class CustomDiagramShape : DiagramShape {
[XtraSerializableProperty]
public string DatabaseObjectID { get; set; }
static CustomDiagramShape() {
DiagramControl.ItemTypeRegistrator.Register(typeof(CustomDiagramShape));
}
}
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"]);
}
}