Back to Devexpress

How to: Create a DiagramShape Descendant and Serialize Its Properties

wpf-118073-controls-and-libraries-diagram-control-examples-how-to-create-a-diagramshape-descendant-and-serialize-its-properties.md

latest9.3 KB
Original Source

How to: Create a DiagramShape Descendant and Serialize Its Properties

  • Jun 07, 2019
  • 3 minutes to read

This example demonstrates how to serialize custom data using DiagramControl‘s serialization mechanism. In the example, the DiagramShape.Content property of diagram shapes is loaded from data objects every time the diagram is shown. To associate shapes with data objects, the DatabaseObjectID property is added at the DiagramShape descendant level. To serialize this property along with standard DiagramShape properties, perform the following steps:

Note

In certain scenarios, it is easier to use the DiagramShape.Tag property to store custom data without creating DiagramShape descendants. In this case, no further steps are needed as the Tag property is serialized by default.

  1. Mark your custom property with the XtraSerializableProperty attribute:
csharp
[XtraSerializableProperty]
public int DatabaseObjectID { get; set; }
  1. Call the DiagramItemTypeRegistrator.Register method to register your custom shape type for serialization. Custom shape types should be registered at the application start. If the custom shape is used in the Diagram Designer Control or Item Template Designer, it is necessary to also register it in the shape type’s static constructor.
csharp
DiagramControl.ItemTypeRegistrator.Register(typeof(DiagramShapeEx));

To allow end-users to edit your custom property in the Properties Panel, handle the DiagramControl.CustomGetEditableItemProperties event.

csharp
private void diagramControl1_CustomGetEditableItemProperties(object sender, DiagramCustomGetEditableItemPropertiesEventArgs e) {
    if (e.Item is DiagramShapeEx) {
        e.Properties.Add(TypeDescriptor.GetProperties(typeof(DiagramShapeEx))["DatabaseObjectID"]);
    }
}

View Example

csharp
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Windows;
using DevExpress.Diagram.Core;
using DevExpress.Utils.Serializing;
using DevExpress.Xpf.Diagram;

namespace DXDiagram.CustomShapeProperties {
    public class DiagramShapeEx : DiagramShape {
        [XtraSerializableProperty]
        public string Description { get; set; }
        [XtraSerializableProperty]
        public int ShapeID { get; set;}
        static DiagramShapeEx() {
            DiagramControl.ItemTypeRegistrator.Register(typeof(DiagramShapeEx));
        }
    }
}
xml
<XtraSerializer version="16.1.0.0">
  <Items>
    <Item1 ItemKind="DiagramRoot" PageSize="800,600" SelectedStencils="BasicShapes, CustomStencil">
      <Children>
        <Item1 Position="100,42" Size="300,100" Angle="0" Shape="BasicShapes.Ellipse" ItemKind="DiagramShapeEx" Description="EllipseDescription" ShapeID="5" />
        <Item2 Position="100,320" Size="300,50" Angle="0" Shape="BasicShapes.Rectangle" ItemKind="DiagramShapeEx" Description="RectangleDescription" ShapeID="6" />
        <Item3 Position="100,180" Size="300,100" Angle="0" Shape="BasicShapes.Ellipse" Content="standard ellipse" ItemKind="DiagramShape" />
        <Item4 Position="100,400" Size="300,50" Angle="0" Shape="BasicShapes.Rectangle" Content="standard rectangle" ItemKind="DiagramShape" />
        <Item5 Position="500,200" Size="100,110" Angle="0" Shape="BasicShapes.Star6" ItemKind="DiagramShape" />
        <Item6 BeginItemPointIndex="1" EndItemPointIndex="0" Points="550,92" ItemKind="DiagramConnector" BeginItem="0" EndItem="4" BeginPoint="400,92" EndPoint="550,200" />
        <Item7 BeginItemPointIndex="1" EndItemPointIndex="10" Points="490,230 490,227.5" ItemKind="DiagramConnector" BeginItem="2" EndItem="4" BeginPoint="400,230" EndPoint="506.698729810778,227.5" />
        <Item8 BeginItemPointIndex="1" EndItemPointIndex="8" Points="490,345 490,282.5" ItemKind="DiagramConnector" BeginItem="1" EndItem="4" BeginPoint="400,345" EndPoint="506.698729810778,282.5" />
        <Item9 BeginItemPointIndex="1" EndItemPointIndex="6" Points="550,425" ItemKind="DiagramConnector" BeginItem="3" EndItem="4" BeginPoint="400,425" EndPoint="550,310" />
      </Children>
    </Item1>
  </Items>
</XtraSerializer>
csharp
using System.Windows;
using DevExpress.Diagram.Core;
using DevExpress.Xpf.Diagram;
using System.ComponentModel;

namespace DXDiagram.CustomShapeProperties {
    public partial class MainWindow : Window {
        public MainWindow() {
            InitializeComponent();
            RegisterStencil();
            LoadData();
        }
        void LoadData() {
            diagramControl.DocumentSource = "DiagramData.xml";
        }
        void RegisterStencil() {
            var stencil = new DevExpress.Diagram.Core.DiagramStencil("CustomStencil", "Custom Shapes");
            var itemTool = new FactoryItemTool("CustomShape", () => "Custom Shape", diagram => { DiagramShapeEx customShape = new DiagramShapeEx() { Width = 100, Height = 50 }; return customShape; }, new System.Windows.Size(100, 50), false);
            stencil.RegisterTool(itemTool);
            DevExpress.Diagram.Core.DiagramToolboxRegistrator.RegisterStencil(stencil);
            DiagramControl.ItemTypeRegistrator.Register(typeof(DiagramShapeEx));
        }

        private void diagramControl_CustomGetEditableItemProperties(object sender, DiagramCustomGetEditableItemPropertiesEventArgs e) {
            if (e.Item is DiagramShapeEx) {
                e.Properties.Add(TypeDescriptor.GetProperties(typeof(DiagramShapeEx))["Description"]);
            }
        }
    }
}
xaml
<Window x:Class="DXDiagram.CustomShapeProperties.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:DXDiagram.CustomShapeProperties"
        xmlns:dxdiag="http://schemas.devexpress.com/winfx/2008/xaml/diagram" 
        mc:Ignorable="d"
        Title="MainWindow" Height="700" Width="1100">
    <Grid>
        <dxdiag:DiagramDesignerControl Name="diagramControl" CustomGetEditableItemProperties="diagramControl_CustomGetEditableItemProperties" />
    </Grid>
</Window>
vb
Imports DevExpress.Diagram.Core
Imports DXDiagram.CustomShapeProperties.DXDiagram.CustomShapeProperties
Imports System.ComponentModel

Class MainWindow
    Public Sub New()
        InitializeComponent()
        RegisterStencil()
        LoadData()
    End Sub
    Private Sub LoadData()
        diagram.DocumentSource = "DiagramData.xml"
    End Sub
    Private Sub RegisterStencil()
        Dim stencil = New DevExpress.Diagram.Core.DiagramStencil("CustomStencil", "Custom Shapes")
        stencil.RegisterTool(New FactoryItemTool("CustomShape", Function() "Custom Shape", Function(diagram) New DiagramShapeEx(), New System.Windows.Size(230, 110), False))
        DevExpress.Diagram.Core.DiagramToolboxRegistrator.RegisterStencil(stencil)
        DevExpress.Xpf.Diagram.DiagramControl.ItemTypeRegistrator.Register(GetType(DiagramShapeEx))
    End Sub

    Private Sub diagram_CustomGetEditableItemProperties(sender As Object, e As DevExpress.Xpf.Diagram.DiagramCustomGetEditableItemPropertiesEventArgs) Handles diagram.CustomGetEditableItemProperties
        If TypeOf e.Item Is DiagramShapeEx Then
            e.Properties.Add(TypeDescriptor.GetProperties(GetType(DiagramShapeEx))("Description"))
        End If
    End Sub
End Class
vb
Imports System.Collections.Generic
Imports System.ComponentModel
Imports System.Linq
Imports System.Windows
Imports DevExpress.Diagram.Core
Imports DevExpress.Xpf.Diagram
Imports DevExpress.Utils.Serializing

Namespace DXDiagram.CustomShapeProperties

    Public Class DiagramShapeEx
        Inherits DiagramShape

        <XtraSerializableProperty>
        Public Property Description() As String

        <XtraSerializableProperty>
        Public Property ShapeID() As Integer

        Shared Sub New()
            DiagramControl.ItemTypeRegistrator.Register(GetType(DiagramShapeEx))
        End Sub

    End Class

End Namespace