This is a migrated thread and some comments may be shown as answers.

Custom RadDiagramConnector Shape and XML Diagram Serialization

4 Answers 42 Views
Diagram
This is a migrated thread and some comments may be shown as answers.
Valentin
Top achievements
Rank 1
Valentin asked on 14 Aug 2018, 01:01 PM

Hi Telerik,

 

I'm using a RadDiagram with a custom RadDiagramConnection :

<Style TargetType="diagramscontrols:RadDiagramConnection" x:Key="RadDiagramConnectionStyle_RotateText">
    <Setter Property="StrokeThickness" Value="1"/>
    <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
    <Setter Property="VerticalContentAlignment" Value="Stretch"/>
    <Setter Property="FocusVisualStyle" Value="{x:Null}"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="telerik:RadDiagramConnection">
                <Grid x:Name="RootTemplate" MinHeight="0" HorizontalAlignment="Stretch">
                    <VisualStateManager.VisualStateGroups>
                        <VisualStateGroup x:Name="SelectionStates">
                            <VisualState x:Name="Selected"/>
                            <VisualState x:Name="SelectedInGroup">
                                <Storyboard>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="SelectedInGroupPath" Storyboard.TargetProperty="Visibility" Duration="0">
                                        <DiscreteObjectKeyFrame KeyTime="0">
                                            <DiscreteObjectKeyFrame.Value>
                                                <Visibility>Visible</Visibility>
                                            </DiscreteObjectKeyFrame.Value>
                                        </DiscreteObjectKeyFrame>
                                    </ObjectAnimationUsingKeyFrames>
                                </Storyboard>
                            </VisualState>
                            <VisualState x:Name="Unselected"/>
                            <VisualState x:Name="SelectedAsGroup"/>
                        </VisualStateGroup>
                        <VisualStateGroup x:Name="EditMode">
                            <VisualState x:Name="NormalMode"/>
                            <VisualState x:Name="NormalEditMode">
                                <Storyboard>
                                    <ObjectAnimationUsingKeyFrames Duration="0" Storyboard.TargetName="NormalContent" Storyboard.TargetProperty="Visibility">
                                        <DiscreteObjectKeyFrame KeyTime="0">
                                            <DiscreteObjectKeyFrame.Value>
                                                <Visibility>Collapsed</Visibility>
                                            </DiscreteObjectKeyFrame.Value>
                                        </DiscreteObjectKeyFrame>
                                    </ObjectAnimationUsingKeyFrames>
                                    <ObjectAnimationUsingKeyFrames Duration="0" Storyboard.TargetName="EditContent" Storyboard.TargetProperty="Visibility">
                                        <DiscreteObjectKeyFrame KeyTime="0">
                                            <DiscreteObjectKeyFrame.Value>
                                                <Visibility>Visible</Visibility>
                                            </DiscreteObjectKeyFrame.Value>
                                        </DiscreteObjectKeyFrame>
                                    </ObjectAnimationUsingKeyFrames>
                                </Storyboard>
                            </VisualState>
                            <VisualState x:Name="TextBoxEditMode">
                                <Storyboard>
                                    <ObjectAnimationUsingKeyFrames Duration="0" Storyboard.TargetName="NormalContent" Storyboard.TargetProperty="Visibility">
                                        <DiscreteObjectKeyFrame KeyTime="0">
                                            <DiscreteObjectKeyFrame.Value>
                                                <Visibility>Collapsed</Visibility>
                                            </DiscreteObjectKeyFrame.Value>
                                        </DiscreteObjectKeyFrame>
                                    </ObjectAnimationUsingKeyFrames>
                                    <ObjectAnimationUsingKeyFrames Duration="0" Storyboard.TargetName="EditTextBox" Storyboard.TargetProperty="Visibility">
                                        <DiscreteObjectKeyFrame KeyTime="0">
                                            <DiscreteObjectKeyFrame.Value>
                                                <Visibility>Visible</Visibility>
                                            </DiscreteObjectKeyFrame.Value>
                                        </DiscreteObjectKeyFrame>
                                    </ObjectAnimationUsingKeyFrames>
                                </Storyboard>
                            </VisualState>
                        </VisualStateGroup>
                    </VisualStateManager.VisualStateGroups>
                    <Path x:Name="DeferredPath"
                               Stroke="{TemplateBinding Stroke}"
                               Opacity="0.7"
                               Fill="{TemplateBinding Background}"
                               StrokeThickness="{TemplateBinding StrokeThickness}"
                               StrokeDashArray="2 2"/>
                    <Path x:Name="SelectedInGroupPath" Visibility="Collapsed" Stroke="Green" />
                    <Path Stroke="{TemplateBinding Stroke}"
                              Fill="{TemplateBinding Background}"
                              StrokeThickness="{TemplateBinding StrokeThickness}"
                              x:Name="GeometryPath"
                              StrokeDashArray="{TemplateBinding StrokeDashArray}"/>
                    <Grid x:Name="EdittingElement" RenderTransformOrigin="0.5 0.5" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
                        <Grid.LayoutTransform>
                            <RotateTransform>
                                <RotateTransform.Angle>
                                    <MultiBinding Converter="{StaticResource PointsToAngleConverter}">
                                        <Binding Path="StartPoint" RelativeSource="{RelativeSource AncestorType=telerik:RadDiagramConnection}" />
                                        <Binding Path="EndPoint" RelativeSource="{RelativeSource AncestorType=telerik:RadDiagramConnection}" />
                                        <Binding ElementName="DeferredPath" Path="Data" />
                                    </MultiBinding>
                                </RotateTransform.Angle>
                            </RotateTransform>
                        </Grid.LayoutTransform>
                        <Border Background="Transparent"/>
                        <TextBlock x:Name="NormalContent" Foreground="{TemplateBinding Foreground}" FontFamily="{TemplateBinding FontFamily}" FontSize="{TemplateBinding FontSize}"
                                   Text="{TemplateBinding Content}" TextAlignment="{Binding Tag.TextAlignement, RelativeSource={RelativeSource AncestorType=diagramscontrols:RadDiagramConnection}}"
                                   HorizontalAlignment="{Binding Tag.HorizontalTextAlignement, RelativeSource={RelativeSource AncestorType=diagramscontrols:RadDiagramConnection}}"
                                   VerticalAlignment="Center">
                            <TextBlock.Margin>
                                <MultiBinding Converter="{StaticResource MarginConverter}">
                                    <Binding Path="StartPoint" RelativeSource="{RelativeSource AncestorType=telerik:RadDiagramConnection}" />
                                    <Binding Path="EndPoint" RelativeSource="{RelativeSource AncestorType=telerik:RadDiagramConnection}" />
                                    <Binding Path="ActualHeight" RelativeSource="{RelativeSource Self}" />
                                </MultiBinding>
                            </TextBlock.Margin>
                        </TextBlock>
                        <ContentPresenter x:Name="EditContent" Visibility="Collapsed" Content="{TemplateBinding Content}" ContentTemplate="{TemplateBinding EditTemplate}"/>
                        <TextBox x:Name="EditTextBox" Visibility="Collapsed">
                            <TextBox.InputBindings>
                                <KeyBinding Key="Enter" Command="ApplicationCommands.NotACommand"/>
                            </TextBox.InputBindings>
                        </TextBox>
                    </Grid>
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

 

To save my diagram, I'm using this code :

Dim pathDiagram As String = myDiagram.Save()
Dim xml_doc As XDocument = XDocument.Parse(pathDiagram)

 

The problem is that I want to save the HorizontalAlignement of the text in my custom RadDiagramConnection, and I don't know how I can do this.

For custom TextShape, the HorizontalAlignement is saved, like in the attached picture.

 

Do you know how I can add the save of HorizontalAlignement property during Diagram saving ?

 

Thank you.

Valentin.

 

4 Answers, 1 is accepted

Sort by
0
Martin Ivanov
Telerik team
answered on 17 Aug 2018, 09:49 AM
Hello Valentin,

The diagram serialization features saves a set of predefined properties by default. You can see those in the Extending RadDiagram Serialization section of the serialization article.

To save other properties you can use the ConnectionSerialized and ConnectionDeserialized events of the diagram. Note that that there are also ShapeSerialized and ShapeDeserialized events. The connection events are used the same as the shape events. Basically, in the serialization event handler you can store the Tag property of the connection that holds your text alignment into the SerializationInfo of the event arguments. And in the deserialization event handler get the Tag from the SerializationInfo and set it to the connection.

Regards,
Martin Ivanov
Progress Telerik
Get quickly onboarded and successful with your Telerik and/or Kendo UI products with the Virtual Classroom free technical training, available to all active customers. Learn More.
0
Valentin
Top achievements
Rank 1
answered on 23 Aug 2018, 09:00 AM

Hi Martin,

Thank for the answer.

 

To serialize data, we have this code :

AddHandler Me.ShapeSerialized, AddressOf CustomShapeSerialized
AddHandler Me.ShapeDeserialized, AddressOf CustomShapeDeserialized

And :

Public Sub CustomShapeSerialized(sender As Object, e As Telerik.Windows.Controls.Diagrams.ShapeSerializationRoutedEventArgs)
    Try
        If e.Shape Is Nothing Or Context Is Nothing Then
            Return
        End If
 
        Dim shape As Telerik.Windows.Controls.Diagrams.RadDiagramShapeBase = DirectCast(e.Shape, Telerik.Windows.Controls.Diagrams.RadDiagramShapeBase)
 
        If TypeOf shape Is KCBoxShape Then
            Dim lKCToSerialize As KCBoxModel = DirectCast(shape.DataContext, KCBoxModel)
            lKCToSerialize.AddSerializationInfo(e)
 
        ElseIf TypeOf shape Is GapBoxShape Then
            Dim lGapToSerialize As GapBoxModel = DirectCast(shape.DataContext, GapBoxModel)
            lGapToSerialize.AddSerializationInfo(e)
 
        ElseIf TypeOf shape Is StressBoxShape Then
            Dim lStressToSerialize As StressBoxModel = DirectCast(shape.DataContext, StressBoxModel)
            lStressToSerialize.AddSerializationInfo(e)
 
        ElseIf TypeOf shape Is RefBoxShape Then
            Dim lRefToSerialize As RefBoxModel = DirectCast(shape.DataContext, RefBoxModel)
            lRefToSerialize.AddSerializationInfo(e)
 
        ElseIf TypeOf shape Is CoordinateBoxShape Then
            Dim lCoordinateToSerialize As CoordinateBoxModel = DirectCast(shape.DataContext, CoordinateBoxModel)
            lCoordinateToSerialize.AddSerializationInfo(e)
 
        ElseIf TypeOf shape Is CalculationBoxShape Then
            Dim lCalculationToSerialize As CalculationBoxModel = DirectCast(shape.DataContext, CalculationBoxModel)
            lCalculationToSerialize.AddSerializationInfo(e)
 
        ElseIf TypeOf shape Is AdiruBoxShape Then
            Dim lAdiruToSerialize As AdiruBoxModel = DirectCast(shape.DataContext, AdiruBoxModel)
            lAdiruToSerialize.AddSerializationInfo(e)
 
        ElseIf TypeOf shape Is FsiBoxShape Then
            Dim lFsiToSerialize As FsiBoxModel = DirectCast(shape.DataContext, FsiBoxModel)
            lFsiToSerialize.AddSerializationInfo(e)
 
        ElseIf TypeOf shape Is RadDiagramShape AndAlso TypeOf shape.Content Is Viewbox Then
            Dim lViewBoxImage As Viewbox = DirectCast(shape.Content, Viewbox)
            Dim lImage As Image = TryCast(lViewBoxImage.Child, Image)
            If lImage IsNot Nothing Then
                e.SerializationInfo("ImageId") = DirectCast(shape.Tag, TagPropertiesHolder).ImageShapeId
            End If
 
        ElseIf TypeOf shape Is RadDiagramShape Or TypeOf shape Is RadDiagramTextShape Then
            If TryCast(shape.Tag, TagPropertiesHolder) IsNot Nothing Then
                e.SerializationInfo("HorizontalTextAlignement") = DirectCast(DirectCast(shape.Tag, TagPropertiesHolder).HorizontalTextAlignement, Integer)
            Else
                shape.Tag = New TagPropertiesHolder()
                e.SerializationInfo("HorizontalTextAlignement") = DirectCast(DirectCast(shape.Tag, TagPropertiesHolder).HorizontalTextAlignement, Integer)
            End If
        End If
    Catch ex As Exception
        If Debugger.IsAttached Then Debugger.Break()
        MAAController.MainController.MBox(Portal_Model.Localize.Translate("MirBuilder_ErrorMessage_SerializeShape"), Portal_Model.Localize.Translate("MirBuilder_ErrorMessage_Title"), Forms.MessageBoxButtons.OK, Forms.MessageBoxIcon.Error)
    End Try
 
End Sub

 

The problem is that if I fill the Diagram only with one RadDiagramConnectorShape, my breakpoint is got only for the diagram, and not the connector.

But the default serialization is done because th XML file contains the RadDiagramConnectorShape data.

 

Do you know how I can enter in this sub for RadDiagramConnectorShape ?

 

Thank you.

0
Accepted
Martin Ivanov
Telerik team
answered on 28 Aug 2018, 07:21 AM
Hi Valentin,

This is the sub that is executed when a RadDiagramShape is serializing. In order to save and restore custom properties for the RadDiagramConnection element you will need to the ConnectionSerialized and ConnectionDeserialized events. Can you please try this and let me know how it goes?

Regards,
Martin Ivanov
Progress Telerik
Get quickly onboarded and successful with your Telerik and/or Kendo UI products with the Virtual Classroom free technical training, available to all active customers. Learn More.
0
Valentin
Top achievements
Rank 1
answered on 31 Aug 2018, 09:48 AM

Hi Martin, 

Thank you for the feedback, the Custom event adding is working find !

Tags
Diagram
Asked by
Valentin
Top achievements
Rank 1
Answers by
Martin Ivanov
Telerik team
Valentin
Top achievements
Rank 1
Share this question
or