Click here to Skip to main content
15,890,527 members
Please Sign up or sign in to vote.
5.00/5 (1 vote)
See more:
I am trying to save my list of added tree view parents and children nodes in json formated file - test.json. I was using nested foreach loop, but its not giving me right type of my saving. My adding method look like:
C#
private void InitializeTreeView()
{
  treeView1.Nodes.Add(new TreeNode("chapter1") { Tag = @"\include {chap1}" }); ;
  treeView1.Nodes.Add(new TreeNode("chapter2") { Tag = @"\include {chap2}" });
  treeView1.Nodes.Add(new TreeNode("chapter3") { Tag = @"\include {chap3}" });
  treeView1.Nodes[1].Nodes.Add(new TreeNode("sec21") { Tag = @"\input {sec33}" });
  treeView1.Nodes[1].Nodes.Add(new TreeNode("section22") { Tag = @"\input {sec22}" });
  treeView1.Nodes[2].Nodes.Add(new TreeNode("section31") { Tag = @"\input{sec31}" });
}


Then my Document configuration file for JSON formating looks like:

C#
public class DocPart
   {
      public string NodeTitle { get; set; }
      public bool NodeChecked { get; set; }
      public string ChildTitle { get; set; }
      public bool ChildChecked { get; set; }
   }

   public class DocConfig
   {
      public List<DocPart> Parts { get; set; }

       public static DocConfig LoadFromString(string jsonData)
       {
           var serializer = new DataContractJsonSerializer(typeof(DocConfig));

           var ms = new MemoryStream(Encoding.UTF8.GetBytes(jsonData));
           var config = (DocConfig)serializer.ReadObject(ms);

           return config;

       }
       public string SaveToString()
       {
           var serializer = new DataContractJsonSerializer(typeof(DocConfig));
           var ms = new MemoryStream();
           serializer.WriteObject(ms, this);
           return Encoding.UTF8.GetString(ms.ToArray()).PrettyPrintJson();
       }
   }

I am removing unwanted parent and children nodes with check boxes click. So I want to save check box state to my test.json file. As I said I have tried nested foreach loop, but it is not giving me right options. Maybe you could offer me some tips how to save my tree view in right way? My try of saving:

C#
private void SaveConfig(string path)
   {
       var config = new DocConfig();
       config.Parts = new List<DocPart>();


       foreach (TreeNode node in treeView1.Nodes)
       {
           {
           config.Parts.Add(new DocPart { NodeTitle = node.Text, NodeChecked = node.Checked });
           }

           foreach (TreeNode child in node.Nodes)
           {
           config.Parts.Add(new DocPart { ChildTitle = child.Text, ChildChecked = child.Checked });
           }
           var configString = config.SaveToString();
           File.WriteAllText(path, configString);

      }
   }
Posted
Comments
BillWoodruff 30-Nov-15 4:53am    
Is this a Windows WinForm TreeView Control ?
Member 12175492 30-Nov-15 5:11am    
It is winForms
BillWoodruff 30-Nov-15 7:34am    
I've written code that saves/restores an entire TreeView (with any number of levels), including Checked and other properties. But, you can't serialize a WinForm TreeView TreeNodeCollection directly because of the nature of the WinForms TreeView Control.

In your case, you may not need to serialize/de-serialize an arbitrarily nested TreeNodeCollection.

The answer to these questions will help me to assist you:

1. What exactly is it critical for you to save and restore: the entire TreeView, including properties like Tag and Checked ? ... or ... something less ?

2. you mention "removing unwanted parent and children nodes with check boxes click" : does this mean you don't want to save/restore certain nodes ? please clarify this.

3. is it critical to use JSON ? Would WCF XML work for you ?

4. do you know how to recursively parse a TreeView's TreeNodeCollection ?
Member 12175492 30-Nov-15 7:48am    
1: My project is to make a manual of chapters(parent node) and sections(child node), I want to make my document configuration file, which is written in JSON, because I want to make something like a type of manual. Which I could always reach using as command line parameter. It something like to load previous generated manual. So about my problems: I am saving everything to json file, but its incorrect. It saving every parent and child node as different and not related part. Main thing I don't know how to make sure that parent node has his children nodes.

2.In my application I am adding a lot of chapters and sections. In my case, I want to make a lot of types generated documents. So some times I don't need some chapters or sections in my document.

3. Yes, I need it in Json.

4. I were looking a lot how to parse my treeNodecollection. And a lot suggestions were to make it recursively. But I have tried it and failed to make it.
BillWoodruff 30-Nov-15 8:37am    
"2.In my application I am adding a lot of chapters and sections. In my case, I want to make a lot of types generated documents. So some times I don't need some chapters or sections in my document."

One issue is how to save and restore the TreeView exactly as it is. The issue of how to generate some document by parsing the TreeView and using the 'Checked value of the Node CheckBoxes to determine what gets added to, or left out of, the document ... is another issue.

The CheckBox in each TreeNode in the WinForms TreeView is "independent" of every other CheckBox: you can, through code, make sure that all Child Nodes that inherit from a given Node have their CheckBox values set equal to their Parent.

I'm not going to post full working code here since the code I have written for this scenario was done for a client. What I am going to post is a general outline for how you can achieve saving/restoring the TreeNodes in a WinForms TreeView using JSON.

A. you start off with a simple class to model a TreeNode:
C#
using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;
using System.Windows.Forms;

// in your NameSpace

[DataContract]
public class TNode
{
    [DataMember]
    public TNode Parent { set; get; }

    [DataMember]
    public string Text { set; get; }

    [DataMember]
    public string Tag { set; get; }

    [DataMember]
    public bool CState { set; get; }

    public TNode(TNode parent, string txt, bool cstate, string tag)
    {
        Parent = parent;
        Text = txt;
        CState = cstate;
        Tag = tag;
    }
}
You'll note that the node "model" here has no list of child-nodes: that's by design, and "resurrecting" the correct parent-child relationships is dependent on a certain use of recursion.

B. Then, a Class that will hold the collection of TreeNode "models:"
C#
[DataContract]
public class TNodeCollection
{
    [DataMember]
    public List<TNode> NodeCollection { set; get; }

    public TNodeCollection(TreeNodeCollection nodes)
    {
        NodeCollection = new List<TNode>();

        // for you to write
        ParseTree(null, nodes);
    }

    // for you to write
    //public void SaveJSON() { ... } 
    //public void RestoreJSON(TreeView tv) { ... }

    // to be continued
}
Once you have this "flat list" of TNodes created, it is a simple matter to save that as JSON, and to read it back in, from JSON.

The interesting part is how you recreate from the de-serialized flat list the correct parent-child node relationships. That is achieved by using the fact the node models are created by using depth-first recursion when parsing the TreeView TreeNodeCollection: since Parent Nodes will have been created before their child-nodes, we can use the TreeNodeCollection.Find("nodename", true) method to locate the Parent node as we read the child node, and, then, set the child Node's Parent.

Your code in the Form where you want to save/serialize the TreeView might look like this:
C#
TNodeCollection coll = new TNodeCollection(treeView1.Nodes);

coll.SaveJSON();

coll.RestoreJSON(treeView1);
 
Share this answer
 
v5
I would recommend using JSON tools such as https://codebeautify.org/jsonviewer and https://jsonformatter.org to debug, View and validate JSON data.
 
Share this answer
 
v2

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900