Drag and Drop deserializing

3 posts, 0 answers
  1. Amiel
    Amiel avatar
    13 posts
    Member since:
    Jul 2016

    Posted 25 Sep Link to this post

    I have a RadDiagramToolbox and I populate it in my viewmodel in an ObservableCollection.  I have added a transform to one of the shapes already in the FlowChartShapeType of a 90 degree rotation.  Now it appears properly in the toolbox however when I drag it into the diagram it keeps the shape but I lose the rotation.  I have followed some examples on deserializing and have added what I have in the code behind on the diagram view.  Why doesn't it deserialize properly since Transform is part of Geometry.  

    ViewModel:

     this.Items = new ObservableCollection<MyShape>();

                    var fe_geometry = ShapeFactory.GetShapeGeometry(FlowChartShapeType.ManualOperationShape).Clone();
                    fe_geometry.Transform = new RotateTransform(90);
                    Items .Shapes.Add(new MyShape
                    {
                        Name = $"FE{i}",
                        Geometry = fe_geometry,                                

                    });                
                }

    ----------------------------

    relevant xaml

    View:

      <telerik:RadDiagramToolbox x:Name="toolbox"
                                   Title="Modules"
                                   
                                   
                                   Header="{Binding SelectedItem.Header, RelativeSource={RelativeSource Self}}"
                                   ItemsSource="{Binding Items}"
                                   ItemTemplate="{StaticResource ToolboxGroupTemplate}"
                                   Visibility="{Binding IsChecked, Converter={StaticResource BooleanToVisibilityConverter}, ElementName=toolboxButton}" />

     

    <telerik:RadDiagram Grid.Row="1"  x:Name="diagram" ConnectionBridge="Bow" 
                                                            RouteConnections="True" IsRotationEnabled="False" 
                                                            ScrollViewer.VerticalScrollBarVisibility="Auto"
                                                            ScrollViewer.HorizontalScrollBarVisibility="Auto"
                                                            IsEditable="False"
                                                            IsResizingEnabled="False" ShapeDeserialized="diagram_ShapeDeserialized" ShapeDoubleClicked="diagram_ShapeDoubleClicked"  >

     

    code behind:

      public MainWindow()
            {
                InitializeComponent();        

                //this is when you drag it creates the right shape
                //http://docs.telerik.com/devtools/wpf/controls/raddiagram/howto/drag-custom-toolboxitem
                SerializationService.Default.ItemSerializing += Default_ItemSerializing;
            }

            private void Default_ItemSerializing(object sender, SerializationEventArgs<IDiagramItem> e)
            {
                if (e.Entity is RadDiagramShape)
                {
                    e.SerializationInfo["Geometry"] = (e.Entity as RadDiagramShape).Geometry.ToString(CultureInfo.InvariantCulture);

                    XmlSerializer serializer = new XmlSerializer(typeof(IModule));
                    using (var writer = new StringWriter())
                    {
                        serializer.Serialize(writer, ((e.Entity as RadDiagramShape).DataContext as MyShape).Module);
                        e.SerializationInfo["DataContent2"] = writer.ToString();
                    }
                  
                }
            }

       

                   private void diagram_ShapeDeserialized(object sender, Telerik.Windows.Controls.Diagrams.ShapeSerializationRoutedEventArgs e)
            {
                if (e.Shape as RadDiagramShape != null)
                {
                    (e.Shape as RadDiagramShape).Geometry = GeometryParser.GetGeometry(e.SerializationInfo["Geometry"].ToString()).Clone();
                    

                    var test = e.SerializationInfo["DataContent2"].ToString();
                    XmlSerializer serializer = new XmlSerializer(typeof(IModule));
                    using (var reader = new StringReader(test))
                    {
                        (e.Shape as RadDiagramShape).DataContext = serializer.Deserialize(reader);                  

                    }
                }
            }

         

    Thanks,

    Amiel

     

  2. Amiel
    Amiel avatar
    13 posts
    Member since:
    Jul 2016

    Posted 25 Sep Link to this post

    I understand more what I was trying todo and I see that we are using StreamGeometry which cannot be serialized which is why in the example there is a ToSTring() which doesn't capture the Transform property of the StreamGeometry.  

    What is the best way for serializing/deserializing?   Would be nice if the drag and drop was more seamless not sure if possible.

     

     

  3. Petar Mladenov
    Admin
    Petar Mladenov avatar
    2986 posts

    Posted 28 Sep Link to this post

    Hi Amiel,

    Diagram has built in API for rotating the Shapes - RotationAngle property. Furthermore, it is among the automatically serialized properties. That is why we want to suggest the following solution:

        - the model used for binding the ToolBox Items has RotationAngle property:
    public class ShapeViewModel : NodeViewModelBase
        {
            public double RotationAngle { get; set; }
     
     
            private Geometry geometry;
            public Geometry Geometry
            {
                get { return this.geometry; }
                set
                {
                    if (this.geometry != value)
                    {
                        this.geometry = value;
                        this.OnPropertyChanged("Geometry");
                    }
                }
            }

    - the shape in the toolbox template binds the RotationAngle:
    <DataTemplate x:Key="ToolboxItemTemplate">
                      <Border Width="76" Height="100" Margin="0 1 1 0" Background="Transparent">
                          <Grid>
                              <Grid.RowDefinitions>
                                  <RowDefinition Height="*" />
                                  <RowDefinition Height="Auto" />
                              </Grid.RowDefinitions>
                              <Viewbox Width="64" Height="50" Margin="5 10 5 0"
                               HorizontalAlignment="Center" VerticalAlignment="Top" Stretch="Uniform">
                                  <telerik:RadDiagramShape Margin="15"
                                                   VerticalAlignment="Top"                                                
                                                   HorizontalContentAlignment="Center"
                                                   VerticalContentAlignment="Center"
                                                   Geometry="{Binding Geometry}"
                                                   RotationAngle="{Binding RotationAngle}"
                                                   IsHitTestVisible="False" />

       - then the save/load handles this proeprty automatically and the rotated shape is still rotated after drop

    Pleased find this approach implemented in the attached project.

    Regards,
    Petar Mladenov
    Progress Telerik
    Want to extend the target reach of your WPF applications, leveraging iOS, Android, and UWP? Try UI for Xamarin, a suite of polished and feature-rich components for the Xamarin framework, which allow you to write beautiful native mobile apps using a single shared C# codebase.
Back to Top