windowsforms-404798-controls-and-libraries-diagrams-diagram-items-create-custom-diagram-items-extend-a-default-diagram-item.md
You can create a diagram item descendant with additional properties to extend a default diagram item.
View Example: Create a DiagramShape Descendant with Editable and Serializable Properties
Create a custom class and inherit it from the required type (DiagramShape, DiagramContainer, DiagramList, DiagramConnector, or DiagramImage):
Call the DiagramItemTypeRegistrator.Register method to register your descendant type and allow its serialization. You should register descendants at application startup.
Register a FactoryItemTool that creates your custom item:
The DiagramControl serializes items and their properties when a user performs the following actions: copy, paste, cut, undo, and redo. The serialization mechanism is also used to save diagrams to a stream or XML document. Mark your custom properties with the XtraSerializableProperty attribute to enable their serialization:
[XtraSerializableProperty]
public int DatabaseObjectID { get; set; }
<XtraSerializableProperty>
Public Property DatabaseObjectID As Integer
Handle the DiagramControl.CustomGetSerializableItemProperties event instead if you cannot change your diagram item implementation:
void diagramControl1_CustomGetSerializableItemProperties(object sender, DiagramCustomGetSerializableItemPropertiesEventArgs e) {
e.Properties.Add(TypeDescriptor.GetProperties(typeof(CustomDiagramShape))["DatabaseObjectID"]);
}
Private Sub diagramControl1_CustomGetSerializableItemProperties(ByVal sender As Object, ByVal e As DiagramCustomGetSerializableItemPropertiesEventArgs)
e.Properties.Add(TypeDescriptor.GetProperties(GetType(CustomDiagramShape))("DatabaseObjectID"))
End Sub
You can also handle the DiagramControl.CustomGetEditableItemProperties event to allow users to edit your custom properties in the Properties Panel:
void diagramControl1_CustomGetEditableItemProperties(object sender, DiagramCustomGetEditableItemPropertiesEventArgs e) {
if (e.Item is CustomDiagramShape) {
e.Properties.Add(TypeDescriptor.GetProperties(typeof(CustomDiagramShape))["DatabaseObjectID"]);
}
}
Private Sub diagramControl1_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
The Properties Panel allows users to edit properties that are not defined directly at the diagram item level (for example, when your diagram is bound to a data source and you need to edit source item properties). To do this, handle the DiagramControl.CustomGetEditableItemProperties event and use the CreateProxyProperty method to create a custom property descriptor.
The Properties Panel uses the Property Grid control to edit properties. This control supports custom TypeConverters that can be assigned to properties of a diagram item descendant. You can use these converters when editable properties are object collections or custom types.
public class CollectionDescriptionConverter : CollectionConverter {
public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, object value, Attribute[] attributes) {
if (value is List<int> list)
return new PropertyDescriptorCollection(list.Select(x => new CustomPropertyDescriptor(Guid.NewGuid().ToString())), new Attribute[] { ... });
return base.GetProperties(context, value, attributes);
}
public override bool GetPropertiesSupported(ITypeDescriptorContext context) => true;
}
public class CustomPropertyDescriptor : PropertyDescriptor { ... }
public class CustomDiagramShape : DiagramShape {
[TypeConverter(typeof(CollectionDescriptionConverter))]
public ObservableCollection<string> _Values { get; set; }
}
Public Class CollectionDescriptionConverter
Inherits CollectionConverter
Public Overrides Function GetProperties(ByVal context As ITypeDescriptorContext, ByVal value As Object, ByVal attributes As Attribute()) As PropertyDescriptorCollection
If TypeOf value Is List(Of Integer) Then
Dim list = CType(value, List(Of Integer))
Return New PropertyDescriptorCollection(list.[Select](Function(x) New CustomPropertyDescriptor(Guid.NewGuid().ToString())), New Attribute() { ... })
End If
Return MyBase.GetProperties(context, value, attributes)
End Function
Public Overrides Function GetPropertiesSupported(ByVal context As ITypeDescriptorContext) As Boolean
Return True
End Function
End Class
Public Class CustomPropertyDescriptor
Inherits PropertyDescriptor
' ...
End Class
Public Class CustomDiagramShape
Inherits DiagramShape
<TypeConverter(GetType(CollectionDescriptionConverter))>
Public Property _Values As ObservableCollection(Of String)
End Class