wpf-118578-controls-and-libraries-diagram-control-data-binding-generating-diagrams-from-a-data-source.md
You can use the DiagramDataBindingBehavior class to generate single and multi-level diagrams from flat (non-hierarchical) data.
Attach DiagramDataBindingBehavior in one of two ways:
Open the DiagramControl‘s Quick Actions and select DiagramDataBindingBehavior :
Add DiagramDataBindingBehavior in XAML or code:
Use the following properties to define source collections for shapes/containers and connectors:
| Property | Description |
|---|---|
| KeyMember | Specifies a data source property that uniquely identifies shapes/containers. |
| ItemsSource | Specifies a source collection of data items that describe shapes/containers. |
| ConnectorsSource | Specifies a source collection of data items that describe connectors. |
| ConnectorFromMember | Specifies a connector item property that identifies the start item by its KeyMember. |
| ConnectorToMember | Specifies a connector item property that identifies the end item by its KeyMember. |
DiagramDataBindingBehavior identifies items by their instances if you do not specify the KeyMember property.
You can also use the Behaviors tab in the control’s Quick Actions to configure DiagramDataBindingBehavior at design-time:
You can use the following techniques to define and configure generated items:
DiagramDataBindingBehavior can obtain values only from strongly typed objects. You cannot bind it to dynamic properties.
The following example demonstrates the DiagramControl bound to sample data:
View Example: Use DiagramDataBindingBehavior to Generate a Diagram from a Collection
<Window ...
xmlns:dxdiag="http://schemas.devexpress.com/winfx/2008/xaml/diagram"
xmlns:dxmvvm="http://schemas.devexpress.com/winfx/2008/xaml/mvvm"
DataContext="{dxmvvm:ViewModelSource Type={x:Type viewModel:ViewModel}}">
<Grid>
<dxdiag:DiagramControl ShowGrid="False" ShowRulers="False" ShowPageBreaks="False" CanvasSizeMode="Fill">
<dxmvvm:Interaction.Behaviors>
<dxdiag:DiagramDataBindingBehavior ItemsSource="{Binding ClassSource}" ConnectorsSource="{Binding ConnectionSource}" ConnectorFromMember="ConnectedFrom" ConnectorToMember="ConnectedTo" KeyMember="ClassName" LayoutKind="Sugiyama" ClearExistingItems="False" GenerateItem="DiagramDataBindingBehavior_GenerateItem" GenerateConnector="DiagramDataBindingBehavior_GenerateConnector">
<dxdiag:DiagramDataBindingBehavior.TemplateDiagram>
<dxdiag:DiagramControl CanvasSizeMode="Fill" SelectedStencils="TemplateDesigner" ShowPageBreaks="false">
<dxdiag:DiagramContainer Anchors="Left, Top" Background="#FFCEE1F2" CanCopyWithoutParent="True" ConnectionPoints="0.5,0 1,0.5 0.5,1 0,0.5" CanAddItems="False" DragMode="ByAnyPoint" Height="78" ItemsCanChangeParent="False" ItemsCanAttachConnectorEndPoint="False" ItemsCanAttachConnectorBeginPoint="False" ItemsCanSelect="False" ItemsCanEdit="False" ItemsCanCopyWithoutParent="False" ItemsCanMove="False" ItemsCanRotate="False" ItemsCanSnapToOtherItems="False" ItemsCanDeleteWithoutParent="False" ItemsCanSnapToThisItem="False" ItemsCanResize="False" Position="25,150" StrokeId="Black" Shape="StandardContainers.Alternating" ShowHeader="False" StrokeDashArray="5 3" ThemeStyleId="ShapeId.Focused1" TemplateName="ClassShape" Width="200">
<dxdiag:DiagramShape Anchors="Left, Top" Angle="0" Background="Transparent" CanAttachConnectorBeginPoint="False" CanResize="False" CanEdit="False" CanCopyWithoutParent="False" CanChangeParent="False" CanMove="False" CanAttachConnectorEndPoint="False" CanSelect="False" CanDeleteWithoutParent="False" CanRotate="False" ForegroundId="Black" FontWeight="Bold" FontFamily="Arial" Height="25" Position="11,10" StrokeThickness="0" ThemeStyleId="Variant2" TextAlignment="Left" Width="176">
<dxdiag:DiagramShape.Bindings>
<dxdiag:DiagramBinding Expression="ClassName" PropertyName="Content"/>
</dxdiag:DiagramShape.Bindings>
</dxdiag:DiagramShape>
<dxdiag:DiagramShape Anchors="Left, Top" Angle="0" Background="Transparent" CanAttachConnectorBeginPoint="False" CanResize="False" CanEdit="False" CanCopyWithoutParent="False" CanChangeParent="False" CanMove="False" CanAttachConnectorEndPoint="False" CanSelect="False" CanDeleteWithoutParent="False" CanRotate="False" ForegroundId="Black_3" FontFamily="Arial" Height="25" Position="11,37.5" Stroke="Transparent" StrokeThickness="0" TextAlignment="Left" Width="176">
<dxdiag:DiagramShape.Bindings>
<dxdiag:DiagramBinding Expression="Type" PropertyName="Content"/>
</dxdiag:DiagramShape.Bindings>
</dxdiag:DiagramShape>
</dxdiag:DiagramContainer>
<dxdiag:DiagramConnector BeginPoint="300,164" CanDragBeginPoint="False" CanChangeRoute="False" CanDragEndPoint="False" EndArrow="ClosedASMEArrow" EndArrowSize="10,10" EndPoint="390,254" Points="(Empty)" StrokeId="Black" TemplateName="ClassConnector" Type="Straight"/>
<dxdiag:DiagramContainer Anchors="Left, Top" BackgroundId="Dark_2" CanCopyWithoutParent="True" ConnectionPoints="0.5,0 1,0.5 0.5,1 0,0.5" CanAddItems="False" DragMode="ByAnyPoint" Height="78" ItemsCanChangeParent="False" ItemsCanAttachConnectorEndPoint="False" ItemsCanAttachConnectorBeginPoint="False" ItemsCanSelect="False" ItemsCanEdit="False" ItemsCanCopyWithoutParent="False" ItemsCanMove="False" ItemsCanRotate="False" ItemsCanSnapToOtherItems="False" ItemsCanDeleteWithoutParent="False" ItemsCanSnapToThisItem="False" ItemsCanResize="False" Position="428,369" StrokeId="Black" Shape="StandardContainers.Alternating" ShowHeader="False" StrokeDashArray="5 3" ThemeStyleId="ShapeId.Focused1" TemplateName="InterfaceShape" Width="200">
<dxdiag:DiagramShape Anchors="Left, Top" Angle="0" Background="Transparent" CanAttachConnectorBeginPoint="False" CanResize="False" CanEdit="False" CanCopyWithoutParent="False" CanChangeParent="False" CanMove="False" CanAttachConnectorEndPoint="False" CanSelect="False" CanDeleteWithoutParent="False" CanRotate="False" ForegroundId="Black" FontWeight="Bold" FontFamily="Arial" Height="25" Position="11,10" StrokeThickness="0" ThemeStyleId="Variant2" TextAlignment="Left" Width="176">
<dxdiag:DiagramShape.Bindings>
<dxdiag:DiagramBinding Expression="ClassName" PropertyName="Content"/>
</dxdiag:DiagramShape.Bindings>
</dxdiag:DiagramShape>
<dxdiag:DiagramShape Anchors="Left, Top" Angle="0" Background="Transparent" CanAttachConnectorBeginPoint="False" CanResize="False" CanEdit="False" CanCopyWithoutParent="False" CanChangeParent="False" CanMove="False" CanAttachConnectorEndPoint="False" CanSelect="False" CanDeleteWithoutParent="False" CanRotate="False" ForegroundId="Black_3" FontFamily="Arial" Height="25" Position="11,37.5" Stroke="Transparent" StrokeThickness="0" TextAlignment="Left" Width="176">
<dxdiag:DiagramShape.Bindings>
<dxdiag:DiagramBinding Expression="Type" PropertyName="Content"/>
</dxdiag:DiagramShape.Bindings>
</dxdiag:DiagramShape>
</dxdiag:DiagramContainer>
<dxdiag:DiagramConnector BeginPoint="500,175" CanDragBeginPoint="False" CanChangeRoute="False" CanDragEndPoint="False" EndArrow="Filled90" EndArrowSize="10,10" EndPoint="590,265" Points="(Empty)" StrokeId="Black" TemplateName="InterfaceConnector" Type="Straight"/>
</dxdiag:DiagramControl>
</dxdiag:DiagramDataBindingBehavior.TemplateDiagram>
</dxdiag:DiagramDataBindingBehavior>
</dxmvvm:Interaction.Behaviors>
</dxdiag:DiagramControl>
</Grid>
</Window>
public class ViewModel {
public List<ClassData> ClassSource { get; set; }
public List<ConnectionData> ConnectionSource { get; set; }
public ViewModel() {
ClassSource = ClassStructureGenerator.ClassList();
ConnectionSource = ClassStructureGenerator.ConnectionList();
}
}
//...
private void DiagramDataBindingBehavior_GenerateItem(object sender, DevExpress.Xpf.Diagram.DiagramGenerateItemEventArgs e) {
if (((ClassData)e.DataObject).Type == ClassType.Interface)
e.Item = e.CreateItemFromTemplate("InterfaceShape");
else e.Item = e.CreateItemFromTemplate("ClassShape");
}
private void DiagramDataBindingBehavior_GenerateConnector(object sender, DevExpress.Xpf.Diagram.DiagramGenerateConnectorEventArgs e) {
if (((ClassData)e.From).Type == ClassType.Interface || ((ClassData)e.To).Type == ClassType.Interface)
e.Connector = e.CreateConnectorFromTemplate("InterfaceConnector");
else e.Connector = e.CreateConnectorFromTemplate("ClassConnector");
}
Public Class ViewModel
Public Property ClassSource() As List(Of ClassData)
Public Property ConnectionSource() As List(Of ConnectionData)
Public Sub New()
ClassSource = ClassStructureGenerator.ClassList()
ConnectionSource = ClassStructureGenerator.ConnectionList()
End Sub
End Class
'...
Private Sub DiagramDataBindingBehavior_GenerateItem(ByVal sender As Object, ByVal e As DevExpress.Xpf.Diagram.DiagramGenerateItemEventArgs)
If CType(e.DataObject, ClassData).Type = ClassType.Interface Then
e.Item = e.CreateItemFromTemplate("InterfaceShape")
Else
e.Item = e.CreateItemFromTemplate("ClassShape")
End If
End Sub
Private Sub DiagramDataBindingBehavior_GenerateConnector(ByVal sender As Object, ByVal e As DevExpress.Xpf.Diagram.DiagramGenerateConnectorEventArgs)
If CType(e.From, ClassData).Type = ClassType.Interface OrElse CType(e.To, ClassData).Type = ClassType.Interface Then
e.Connector = e.CreateConnectorFromTemplate("InterfaceConnector")
Else
e.Connector = e.CreateConnectorFromTemplate("ClassConnector")
End If
End Sub