Back to Devexpress

Generate Diagrams from Flat Data

wpf-118578-controls-and-libraries-diagram-control-data-binding-generating-diagrams-from-a-data-source.md

latest12.0 KB
Original Source

Generate Diagrams from Flat Data

  • Jun 20, 2024
  • 4 minutes to read

You can use the DiagramDataBindingBehavior class to generate single and multi-level diagrams from flat (non-hierarchical) data.

Set Up the Behavior

Attach DiagramDataBindingBehavior in one of two ways:

Use the following properties to define source collections for shapes/containers and connectors:

PropertyDescription
KeyMemberSpecifies a data source property that uniquely identifies shapes/containers.
ItemsSourceSpecifies a source collection of data items that describe shapes/containers.
ConnectorsSourceSpecifies a source collection of data items that describe connectors.
ConnectorFromMemberSpecifies a connector item property that identifies the start item by its KeyMember.
ConnectorToMemberSpecifies 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:

Define and Configure Generated Diagram Items

You can use the following techniques to define and configure generated items:

Usage Notes

DiagramDataBindingBehavior can obtain values only from strongly typed objects. You cannot bind it to dynamic properties.

Example

The following example demonstrates the DiagramControl bound to sample data:

View Example: Use DiagramDataBindingBehavior to Generate a Diagram from a Collection

xaml
<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>
csharp
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");
}
vb
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