How to save multiple diagrams

5 posts, 2 answers
  1. Hyunho
    Hyunho avatar
    23 posts
    Member since:
    Feb 2013

    Posted 13 May 2013 Link to this post

    Hello,

    I'm evaluating telerik controls now, and my company will purchase in this month.

    I want to know how to save multiple diagram pages with MVVM. (You can see this scenario in a attached screenshot)

    Your document and sample is only showing "RadDiagram.Save()" to save a diagram, but my application is generating  a diagram dynamically for each tab content.

    In this case, SerializableGraphSource doesn't know what diagram is connected with it.
    And a diagram instance will be destroyed and recreated when tab control selection is changed.

    Should I make my own save/load functions for this? 
    I would appreciate if you give me some advice.

    Thank you.
  2. Answer
    Miro Miroslavov
    Admin
    Miro Miroslavov avatar
    588 posts

    Posted 15 May 2013 Link to this post

    Hello Hyunho,

     Unfortunatelly, we don't have this functionality built-in. So I would have a ViewModel that has a collection of SerializableGraphSourceBase - this will serve my TabControl ItemsSource. And then I think it shouldn't be very hard to implement serialization of collection of SerializableGraphSourceBase objects. 
    On a side note our RadTabControl can preserve its content on tab change - there is property called IsContentPreserved. If it's true the content won't be destroyed when you change tab.
    Please let us know if you need further assistance on implementing the save/load functionality.

    All the best,
    Miro Miroslavov
    the Telerik team

    Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.

  3. UI for WPF is Visual Studio 2017 Ready
  4. Hyunho
    Hyunho avatar
    23 posts
    Member since:
    Feb 2013

    Posted 20 May 2013 Link to this post

    Hello Miro,
    Thank you for your reply.

    I have another question.

    1. I bound Position of a shape with TwoWay as follows.
    <Style x:Key="imageShapeStyle" TargetType="{x:Type telerik:RadDiagramShape}">
            <Setter Property="Position" Value="{Binding Position, Mode=TwoWay}" />
            <Setter Property="StrokeThickness" Value="0" />
            <Setter Property="ZIndex" Value="1" />
            <Setter Property="Background" Value="Transparent" />
            <Setter Property="Visibility"
                    Value="{Binding IsVisible, Converter={StaticResource BooleanToVisibilityConverter}, Mode=TwoWay}" />
             
            <Setter Property="AllowDrop" Value="False" />
             
            <Setter Property="HorizontalContentAlignment" Value="Center" />
            <Setter Property="VerticalContentAlignment" Value="Center" />
            <Setter Property="ContentTemplate" Value="{StaticResource imageShapeContentTemplate}" />
            <Setter Property="EditTemplate" Value="{StaticResource imageShapeEditTemplate}" />
        </Style>


    2. I made my own ItemViewModel for a shape binding
    public class ItemViewModel : ViewModelBase
        {
            private bool isVisible;
            public bool IsSelected { get; set; }
            public bool IsValid { get; set; }
            private string text;
            private int textSize;
            private Point position;
     
            public ItemViewModel()
            {
                IsValid = true;
                IsVisible = true;
            }
     
            public Point Position
            {
                get
                {
                    return this.position;
                }
                set
                {
                    if (this.position != value)
                    {
                        this.position = value;
                        Debug.WriteLine("position changed....");
                        this.OnPropertyChanged("Position");
                    }
                }
            }


    3. When I drag a shape in a diagram, Position property is changed well.
        But when I cut/copy and paste a shape in a diagram, a pasted shape does not change it's Position property. I don't know why this is happening. 

    I implemented SealizeNode(), DeserializeNode() function as follows.

    public class DiagramGraphSource : IObservableGraphSource, ISerializableGraphSource
       {
           private readonly ObservableCollection<NodeViewModel> items = new ObservableCollection<NodeViewModel>();
           private readonly ObservableCollection<LinkViewModel> links = new ObservableCollection<LinkViewModel>();
     
           public LinkType LinkType { get; set; }
           public NetworkDiagram DiagramView { get; set; }
     
     
           public ObservableCollection<NodeViewModel> InternalItems
           {
               get { return this.items; }
           }
     
           public ObservableCollection<LinkViewModel> InternalLinks
           {
               get { return this.links; }
           }
     
           public IEnumerable Items
           {
               get { return this.items; }
           }
     
           public IEnumerable<ILink> Links
           {
               get { return this.links; }
           }
     
     
           public DiagramGraphSource()
           {
           }
     
           public object CreateNode(IShape shape)
           {
               Debug.WriteLine("create node..");
               return new NodeViewModel();
           }
     
           public void AddNode(object node)
           {
               var item = node as NodeViewModel;
               Debug.WriteLine("add node.."+item.Position.ToString());
               //Point point = new Point(0,0);
               //item.Position = point;
                
               items.Add(item);
           }
     
           public bool RemoveNode(object node)
           {
               Debug.WriteLine("reomove node..");
               var item = node as NodeViewModel;
               bool result = items.Remove(item);
               item.IsValid = false;
               item = null;
               return result;
           }
     
           public void AddLink(ILink link)
           {
               var linkItem = link as LinkViewModel;
               /*
               NodeViewModel source = linkItem.Source;
               NodeViewModel target = linkItem.Target;
     
               if (source != null && target != null)
               {
                   Debug.WriteLine("connection established...");
               }
                */
               UpdateLinkStyle(linkItem);
               links.Add(linkItem);
           }
     
     
           public bool RemoveLink(ILink link)
           {
               var linkItem = link as LinkViewModel;
               bool result = links.Remove(linkItem);
               linkItem.IsValid = false;
               linkItem = null;
               return result;
           }
     
           public ILink CreateLink(object source, object target)
           {
               var itemSource = source as NodeViewModel;
               var itemTarget = target as NodeViewModel;
               var linkItem = new LinkViewModel();
               UpdateLinkStyle(linkItem);
               linkItem.Source = itemSource;
               linkItem.Target = itemTarget;
               return linkItem;
           }
           
           public string GetNodeUniqueId(NodeViewModel node)
           {
               return node.UID;
           }
     
           public void SerializeLink(ILink link, SerializationInfo info)
           {
           }
     
           public ILink DeserializeLink(IConnection connection, SerializationInfo info)
           {
               return null;
           }
     
           public void SerializeNode(object oNode, SerializationInfo info)
           {
               Debug.WriteLine("serialize node..");
               NodeViewModel node = oNode as NodeViewModel;
               SerializeNodeInfo(node, info);
     
               if (node is ImageNodeViewModel)
               {
                   ImageNodeViewModel imageNode = node as ImageNodeViewModel;
                   info["Image"] = imageNode.Image;
               }
           }
     
           public object DeserializeNode(IShape shape, SerializationInfo info)
           {
               Debug.WriteLine("deserialize node..");
               if (info["PropertyType"].ToString() == typeof(NetworkCameraProperty).ToString())
               {
                   CameraNodeViewModel camera = new CameraNodeViewModel();
                   camera.Image = info["Image"].ToString();
     
                   XmlSerializer xmlSerializer = DataManager.Instance.xmlSerializer_NetworkCameraProperty;
                   TextReader reader = new StringReader(info["Property"].ToString());
                   NetworkCameraProperty cameraProperty = xmlSerializer.Deserialize(reader) as NetworkCameraProperty;
                   camera.Property = cameraProperty;
                   DeserializeNodeInfo(camera, info);
                   return camera;
               }
               else if (info["PropertyType"].ToString() == typeof(NvrProperty).ToString())
               {
                   NvrNodeViewModel nvr = new NvrNodeViewModel();
                   nvr.Image = info["Image"].ToString();
     
                   XmlSerializer xmlSerializer = DataManager.Instance.xmlSerializer_NvrProperty;
                   TextReader reader = new StringReader(info["Property"].ToString());
                   NvrProperty nvrProperty = xmlSerializer.Deserialize(reader) as NvrProperty;
                   nvr.Property = nvrProperty;
                   DeserializeNodeInfo(nvr, info);
                   return nvr;
               }
               else if (info["PropertyType"].ToString() == typeof(SwitchProperty).ToString())
               {
                   SwitchNodeViewModel sw = new SwitchNodeViewModel();
                   sw.Image = info["Image"].ToString();
     
                   XmlSerializer xmlSerializer = DataManager.Instance.xmlSerializer_SwitchProperty;
                   TextReader reader = new StringReader(info["Property"].ToString());
                   SwitchProperty swProperty = xmlSerializer.Deserialize(reader) as SwitchProperty;
                   sw.Property = swProperty;
                   DeserializeNodeInfo(sw, info);
                   return sw;
               }
               else if (info["PropertyType"].ToString() == typeof(CmsProperty).ToString())
               {
                   CmsNodeViewModel cms = new CmsNodeViewModel();
                   cms.Image = info["Image"].ToString();
     
                   XmlSerializer xmlSerializer = DataManager.Instance.xmlSerializer_CmsProperty;
                   TextReader reader = new StringReader(info["Property"].ToString());
                   CmsProperty cmsProperty = xmlSerializer.Deserialize(reader) as CmsProperty;
                   cms.Property = cmsProperty;
                   DeserializeNodeInfo(cms, info);
                   return cms;
               }
               else if (info["PropertyType"].ToString() == typeof(SsmProperty).ToString())
               {
                   SsmNodeViewModel ssm = new SsmNodeViewModel();
                   ssm.Image = info["Image"].ToString();
     
                   XmlSerializer xmlSerializer = DataManager.Instance.xmlSerializer_SsmProperty;
                   TextReader reader = new StringReader(info["Property"].ToString());
                   SsmProperty ssmProperty = xmlSerializer.Deserialize(reader) as SsmProperty;
                   ssm.Property = ssmProperty;
                   DeserializeNodeInfo(ssm, info);
                   return ssm;
               }
               else
               {
                   Debug.WriteLine("why here..");
                   NodeViewModel node = new NodeViewModel();
                   DeserializeNodeInfo(node, info);
                   return node;
               }
           }
     
     
           private void SerializeNodeInfo(NodeViewModel node, SerializationInfo info)
           {
               // info["UID"] = node.UID;
               info["Width"] = node.Width;
               info["Height"] = node.Height;
               info["TextSize"] = node.TextSize;
               info["Position"] = node.Position.ToInvariant();
               info["IsVisible"] = node.IsVisible;
     
               XmlSerializer xmlSerializer = null;
               if (node is CameraNodeViewModel)
                   xmlSerializer = DataManager.Instance.xmlSerializer_NetworkCameraProperty;
               else if (node is NvrNodeViewModel)
                   xmlSerializer = DataManager.Instance.xmlSerializer_NvrProperty;
               else if (node is CmsNodeViewModel)
                   xmlSerializer = DataManager.Instance.xmlSerializer_CmsProperty;
               else if (node is SsmNodeViewModel)
                   xmlSerializer = DataManager.Instance.xmlSerializer_SsmProperty;
               else if (node is SwitchNodeViewModel)
                   xmlSerializer = DataManager.Instance.xmlSerializer_SwitchProperty;
     
               if (xmlSerializer != null)
               {
                   StringWriter textWriter = new StringWriter();
                   xmlSerializer.Serialize(textWriter, node.Property);
                   info["PropertyType"] = node.Property.ToString();
                   info["Property"] = textWriter.ToString();
               }
           }
     
           private void DeserializeNodeInfo(NodeViewModel node, SerializationInfo info)
           {
               // node.UID = info["UID"].ToString();
               node.Width = int.Parse(info["Width"].ToString());
               node.Height = int.Parse(info["Height"].ToString());
               node.TextSize = int.Parse(info["TextSize"].ToString());
               node.Position = Utils.ToPoint(info["Position"].ToString()).Value;
               node.IsVisible = bool.Parse(info["IsVisible"].ToString());
               //node.Position = new Point(0, 0);
           }
     
           private void UpdateLinkStyle(LinkViewModel link)
           {
               switch (LinkType)
               {
                   case LinkType.Network10Mbps:
                       link.MainColor = "#A8A8A8";
                       link.Text = "10Mbps";
                       break;
                   case LinkType.Network100Mbps:
                       link.MainColor = "#000000";
                       link.Text = "100Mbps";
                       break;
                   case LinkType.Network1Gbps:
                       link.MainColor = "#09BA00";
                       link.Text = "1Gbps";
                       break;
                   case LinkType.Network10Gbps:
                       link.MainColor = "#0021F7";
                       link.Text = "10Gbps";
                       break;
               }
           }
       }
  5. Answer
    Miro Miroslavov
    Admin
    Miro Miroslavov avatar
    588 posts

    Posted 23 May 2013 Link to this post

    Hi Hyunho,

     The problem occurs because the Serialization by default is serializing the Position property and when desirializing it sets the Position property of the new shape to the appropriate value which removes the binding. 
    There are several ways to prevent this and the easiest for you is to discard the position property in the serialization: 

    public void SerializeNode(object oNode, SerializationInfo info)
        {
            Debug.WriteLine("serialize node..");
            info[SerializationConstants.Position] = string.Empty;
    You can also handle the serialization even of the Diagram and remove it there, inherit the RadDiagramShape and override the serialization there as well.
    Any of the mentioned tricks should work for you.
    Hope this helps. 

    Regards,
    Miro Miroslavov
    Telerik

    Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.

  6. Hyunho
    Hyunho avatar
    23 posts
    Member since:
    Feb 2013

    Posted 24 May 2013 Link to this post

    Hello Miro,

    Thank you very much for your help.
    Now I solved this problem.
Back to Top
UI for WPF is Visual Studio 2017 Ready