I have to convert a TreeView
object to JSON using C#. I am currently using JsonConvert.SerializeObject()
.
public class SubTreeNode : TreeNode
{
public CustomProperties customProperties;
}
public class CustomProperties
{
public string property1 = "Property1";
public string property2 = "Property2";
public string property3 = "Property3";
}
When tried it with JsonConvert.SerializeObject(treeView1.Nodes);
it only returned the top nodes... not the child nodes, sub-child, and so on.
What is the easiest way to serialize and deserialize this TreeView object?
You will need to add methods that produce JSON from each node recursively.
Check out the related post: Serializing a Tree into Json Object .
I was confronted with the same problem: only top nodes are exported with the standard JSON.Net Serializer because, as fero under the above link rightly states, "your TreeNode class is serialized as an array because it implements IEnumerable". It further says you should decorate the TreeNode class with the JsonConverterAttribute. I didn't get this to work.
Here is an alternative. Please note that this may not be seen as the best way to do it. But it is pretty simple:
Create a new hierarchical class with the information you want to export in JSON (in my case, I only want to export part of my treenode-properties, so creating a new simple class made sense twice):
'Simplified version of tree for json
'Compared to TreeNode class, this object is also serializable with the standard JSON.NET Serializer
Public Class JTree
Public children As New List(Of JTree)()
Private _name As String
Public Property name() As String
Get
Return _name
End Get
Set(value As String)
_name = value
End Set
End Property
Private _id As String
Public Property id() As String
Get
Return _id
End Get
Set(value As String)
_id = value
End Set
End Property
End Class
Recursively move your data from TreeView to a new JTree (our custom class):
Public Sub createSimplifiedJSONTree(parentNode As TreeNode, ByRef JTreeSimp As JTree)
'Start recursion on all subnodes
For Each childNode As TreeNode In parentNode.Nodes
Dim jchild As New JTree
jchild.id = childNode.Name
jchild.name = childNode.Text
JTreeSimp.children.Add(jchild)
createSimplifiedJSONTree(childNode, jchild)
Next
End Sub
Write simplified JSON tree to file using JSON.NET Serializer:
Private Sub WriteJSONfromTreeview()
Dim rootNode As TreeNode = TreeView1.Nodes(0)
Dim JTreeSimp As New JTree
createSimplifiedJSONTree(rootNode, JTreeSimp)
'serialize JSON directly to a file using JSON.Net Serializer
Using file__1 As StreamWriter = File.CreateText("c:\temp\test.txt")
Dim serializer As New JsonSerializer()
serializer.Formatting = Formatting.Indented
serializer.Serialize(file__1, JTreeSimp)
End Using
End Sub
Final txt (example):
{
"children": [
{
"children": [
{
"children": [
{
"children": [
{
"children": [
{
"children": [
{
"children": [
{
"children": [],
"name": "alcatraz",
"id": "021_3",
"size": 166
}
],
"name": "skyline",
"id": "031_3",
"size": 167
}
],
"name": "city",
"id": "041_5",
"size": 167
}
],
"name": "coit",
"id": "051_4",
"size": 169
}
],
"name": "tower",
"id": "061_3",
"size": 170
}
],
"name": "telegraphhill",
"id": "071_3",
"size": 170
}
],
"name": "coittower",
"id": "081_2",
"size": 170
},
{
"children": [
{
"children": [],
"name": "sunset",
"id": "071_112",
"size": 3
}
],
"name": "berkeley",
"id": "081_109",
"size": 3
},
{
"children": [
{
"children": [],
"name": "marin",
"id": "071_77",
"size": 3
}
],
"name": "marinheadlands",
"id": "081_110",
"size": 3
}
],
"name": "root",
"id": "000",
"size": 0
}
This is my solution:
First I create a node class that contains the data structure I want for the nodes, and a JSon method that serialize the object
[JsonObject(ItemNullValueHandling = NullValueHandling.Ignore)] private class node { public node() { this.children = new List<node>(); } public node(string _value, List<node> _children = null, bool _isChecked = false) { Value = _value; isChecked = _isChecked; if (_children != null) { children = _children; } } [JsonProperty("value")] public string Value { get; set; } [JsonProperty("isChecked")] public bool isChecked { get; set; } [JsonProperty("children", NullValueHandling = NullValueHandling.Ignore)] public List<node> children { get; set; } [JsonIgnore] public string JSon { get { return JsonConvert.SerializeObject(this); } } }
I wrote a method that it's meant to be called recursively. This returns a list of the children nodes given a particular tree node
private List<node> RunNode(TreeNode node) { List<node> nodeOut = new List<node>(); foreach(TreeNode child in node.Nodes) { List<node> grandchild = RunNode(child); nodeOut.Add(new node(child.Text, grandchild, child.Checked)); } return nodeOut; }
I wrote and update object method to create a root node where I can contain all the nodes of the treeview. I decided to use a root node instead of a list of nodes, because a list wouldn't have the JSon method that serialize the object.
private void ActualizarMenus() { List<node> parents= new List<node>(); foreach (TreeNode node in trw.Nodes) { List<node> childs = RunNode(node); parents.Add(new node(node.Text,childs,node.Checked)); } root = new node("root", parents, true); }
The root object must be declared as a single node
private node root;
and you can just call the JSon method of root
MessageBox.show(root.JSon());
I hope this helps
using custom json serializer worked for me
var settings = new JsonSerializerSettings
{
Converters = new List<JsonConverter> { new OrgChartConverter() },
Formatting = Formatting.Indented
};
string json = JsonConvert.SerializeObject(tree, settings);
public class OrgChartConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return typeof(Node<T>).IsAssignableFrom(objectType);
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
Node<T> node = (Node<T>)value;
JObject obj = new JObject();
obj.Add("Name", node.Value.Name);
obj.Add("Children", JArray.FromObject(node.Children, serializer));
obj.WriteTo(writer);
}
public override bool CanRead
{
get { return false; }
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.