Edit this page

Serialization

RadDiagram Framework allows you to serialize (save) your current diagram in an XML string and later deserialize it (load). You can achieve this with the RadDiagram.Save() and RadDiagram.Load(string serializationString) methods. You may also use the DiagramCommands Save and Open.

Save And Load A RadDiagram

In the code below you can see how to save and load a RadDiagram using Commands. Please note that before saving the current diagramming structure, it is best to check whether there are any items to save:

Please note that the examples in this tutorial are showcasing Telerik Windows8 theme. In the Setting a Theme article you can find more information on how to set an application-wide theme.

XAML

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
        <RowDefinition Height="*" />
    </Grid.RowDefinitions>
    <StackPanel Orientation="Horizontal">
        <telerik:RadButton Width="125" 
                           Command="telerik:DiagramCommands.Save"
                           CommandTarget="{Binding ElementName=diagram}"
                           Content="Save" />
        <telerik:RadButton Width="125" 
                           Command="telerik:DiagramCommands.Clear"
                           CommandTarget="{Binding ElementName=diagram}"
                           Content="Clear" />
        <telerik:RadButton Width="125" 
                           Command="telerik:DiagramCommands.Open"
                           CommandTarget="{Binding ElementName=diagram}"
                           Content="Load" />
    </StackPanel>
    <telerik:RadDiagram x:Name="diagram" Grid.Row="1">
        <telerik:RadDiagramShape  />
        <telerik:RadDiagram.CommandBindings>
            <CommandBinding Command="telerik:DiagramCommands.Save" Executed="CommandBinding_Executed_Save" CanExecute="CommandBinding_CanExecute"/>
            <CommandBinding Command="telerik:DiagramCommands.Open" Executed="CommandBinding_Executed_Open" />
        </telerik:RadDiagram.CommandBindings>
    </telerik:RadDiagram>
</StackPanel>

C#

private string diagramXMLString;       

public MainWindow()
{
    StyleManager.ApplicationTheme = new Windows8Theme();
    InitializeComponent();          
}

private void CommandBinding_Executed_Save(object sender, ExecutedRoutedEventArgs e)
{
   diagramXMLString =  this.diagram.Save();
}

private void CommandBinding_Executed_Open(object sender, ExecutedRoutedEventArgs e)
{
    if (diagramXMLString != null)
    {
        this.diagram.Load(diagramXMLString);
    }
}

private void CommandBinding_CanExecute(object sender, CanExecuteRoutedEventArgs e)
{
    e.CanExecute = this.diagram.Items.Count > 0;
}

VB.NET

Private diagramXMLString As String

Public MainWindow()
    StyleManager.ApplicationTheme = New Windows8Theme()
    InitializeComponent()
End Sub

Private Sub CommandBinding_Executed_Save(ByVal sender As Object, ByVal e As ExecutedRoutedEventArgs)
    diagramXMLString = Me.diagram.Save()
End Sub

Private Sub CommandBinding_Executed_Open(ByVal sender As Object, ByVal e As ExecutedRoutedEventArgs)
    If diagramXMLString IsNot Nothing Then
        Me.diagram.Load(diagramXMLString)
    End If
End Sub

Private Sub CommandBinding_CanExecute(ByVal sender As Object, ByVal e As CanExecuteRoutedEventArgs)
    e.CanExecute = Me.diagram.Items.Count > 0
End Sub

raddiagrams features serialization

Please note that the Content of the Shapes and the Connections is serialized as String. This means that if you have control like ListBox or TreeView as a Content , it will be not serialized successfully.

Extending RadDiagram Serialization

By default, not every property of the RadDiagramItem is serialized. Below is the list of the properties that are automatically serialized:

These properties are serialized in scenarios where data bindings are not involved. If you are using Binding in styles targeting any of the diagram items, you need to manually serialise and deserialize all the properties that are bound. This is demonstrated in the Manual Serialization/Deserialization section of this article.

  • RadDiagram

    • AllowCopy
    • AllowCut
    • AllowDelete
    • AllowPaste
    • ConnectionBridges
    • ConnectionRoundedCorners
    • IsBackgroundSurfaceVisible
    • IsConnectorsManipulationEnabled
    • IsDraggingEnabled
    • IsEditable
    • IsManipulationAdornerVisible
    • IsPanEnabled
    • IsResizingEnabled
    • IsRotationEnabled
    • IsSnapEnabled
    • IsZoomEnabled
    • Metadata
    • Position
    • RouteConnections
    • SelectionMode
    • SnapX
    • SnapY
    • Zoom
  • RadDiagramShape

    • AllowCopy
    • AllowDelete
    • AllowPaste
    • Background
    • BorderBrush
    • BorderThickness
    • Content
    • FontFamily
    • FontSize
    • FontWeight
    • Foreground
    • Geometry
    • GlidingStyle
    • Id
    • IsConnectionManipulationEnabled
    • IsDraggingEnabled
    • IsEditable
    • IsResizingEnabled
    • IsRotationEnabled
    • MaxHeight
    • MaxWidth
    • MinHeight
    • MinWidth
    • ParentGroup
    • Position
    • RotationAngle
    • Size
    • Stroke
    • StrokeDashArray
    • StrokeThickness
    • UseDefaultConnectors
    • ZIndex
  • RadDiagramConnection

    • AllowCopy
    • AllowDelete
    • AllowPaste
    • Background
    • BezierEndPoint
    • BezierStartPoint
    • BezierTention
    • BorderBrush
    • BorderThickness
    • ConnectionPoints
    • ConnectionType
    • Content
    • EndPoint
    • FontFamily
    • FontSize
    • FontWeight
    • Foreground
    • Id
    • IsConnectionManipulationEnabled
    • IsDraggingEnabled
    • IsEditable
    • IsModified
    • IsResizingEnabled
    • IsRotationEnabled
    • ParentGroup
    • Position
    • Source
    • SourceCapSize
    • SourceCapType
    • SourceConnectorPosition
    • StartPoint
    • Stroke
    • StrokeDashArray
    • StrokeThickness
    • Target
    • TargetCapSize
    • TargetCapType
    • TargetConnectorPosition
    • ZIndex

For every other property that you need to be part of the Serialization/Deserialization process, you have to use the RadDiagram.ShapeDeserialized and RadDiagram.ShapeSerialized or RadDiagram.ConnectionDeserialized and RadDiagram.ConnectionSerialized events. Below is shown how you can serialized the Opacity of the Shapes:

Manual Serialization/Deserialization

If you are using MVVM approach and need to serialize databound properties you can take a look at our Serialize a Databound Diagram article.

C#

void diagram_ShapeDeserialized(object sender, ShapeSerializationRoutedEventArgs e)
{
     // load the saved property
     (e.Shape as RadDiagramShape).Opacity = Convert.ToDouble(e.SerializationInfo["Opacity"], CultureInfo.InvariantCulture);
}

void diagram_ShapeSerialized(object sender, ShapeSerializationRoutedEventArgs e)
{
     // save custom or other property
     e.SerializationInfo["Opacity"] = (e.Shape as RadDiagramShape).Opacity.ToInvariant();
}         

VB.NET

Private Sub diagram_ShapeDeserialized(ByVal sender As Object, ByVal e As ShapeSerializationRoutedEventArgs)
     ' load the saved property'
     TryCast(e.Shape, RadDiagramShape).Opacity = Convert.ToDouble(e.SerializationInfo("Opacity"), CultureInfo.InvariantCulture)
End Sub

Private Sub diagram_ShapeSerialized(ByVal sender As Object, ByVal e As ShapeSerializationRoutedEventArgs)
     ' save custom or other property'
     e.SerializationInfo("Opacity") = (TryCast(e.Shape, RadDiagramShape)).Opacity.ToInvariant()
End Sub 

Please note that the Double.ToInvariant() extension method is defined in the Telerik.Windows.Diagrams.Core namespace and in order to use it in your application, you'll have to add a using statement: using Telerik.Windows.Diagrams.Core;

Preserve bindings to the automatically serialized properties

If you have a binding between a RadDiagramItem property that is automatically serialized and a property from the item’s view model the binding won’t work after the deserialization. This is because the serialization/deserialization logic of the diagram sets those properties locally which has bigger priority than a binding. You can read more about the value setting precedence in the Dependency Property Value Precedence MSDN article.

In order to preserve the binding you can remove the value of the property from the serialization info and use another key to serialize/deserialize it.

For example, if you have a binding to the Position property you can use the following approach for saving the binding:

  • Override the SerializeNode() method of the diagram’s GraphSource and set the value of the bound property to null in the SerializationInfo. Then add the value with a new key in the serialization info.

    C#

    public override void SerializeNode(NodeViewModelBase node, SerializationInfo info)
    {
           var position = info["Position"];
           info["Position"] = null;
           info["MyPosition"] = position;
           base.SerializeNode(node, info);
    }   
    

    VB.NET

    public Overrides Sub SerializeNode(node As NodeViewModelBase, info As SerializationInfo)
        Dim position = info("Position")
        info("Position") = Nothing
        info("MyPosition") = position
        MyBase.SerializeNode(node, info)
    End Sub
    
  • Override the DeserializeNode() method of the diagram’s GraphSource and get the value of the bound property. Then assign it to the property of the view model.

    C#

    public override NodeViewModelBase DeserializeNode(IShape shape, Telerik.Windows.Diagrams.Core.SerializationInfo info)
    {
        var node = base.DeserializeNode(shape, info);
        if (info["MyPosition"] != null)
        {
             var position = Utils.ToPoint(info["MyPosition"].ToString());
         node.Position = position.Value;
        }
        return node;
    }
    

    VB.NET

    Public Overrides Function DeserializeNode(shape As IShape, info As Telerik.Windows.Diagrams.Core.SerializationInfo) As NodeViewModelBase
        Dim node = MyBase.DeserializeNode(shape, info)
        If info("MyPosition") IsNot Nothing Then
            Dim position = Utils.ToPoint(info("MyPosition").ToString())
            node.Position = position.Value
        End If
    Return node
    

    End Function

The code snippets above demonstrate how to preserve the bindings in an MVVM scenario with a custom GraphSource. If you have statically declared shapes you can use the ShapeSerialized and ShapeDeserialized events of the diagram.

See Also