如何使用JSON数据递归填充TreeView

我有一个winforms树视图,我可以自动读取数据,(一个等于key的节点,里面的节点等于value),但是当读取对象类型时,它内部的值不会是对象的子节点节点(对象的键),(也许我无法解释,这是截图和我的方法。)

layer0需要在纹理内部,并且缩放需要在显示内部

layer0需要在纹理内部,并且缩放需要在显示内部

我的杰森:

{ "parent": "builtin/generated", "textures": { "layer0": "mm:items/iron_dust" }, "display": { "scale": [ 1.7, 1.7, 1.7 ] } } 

我自动检测的方法(实际上不是全部我的)

 private void Form1_Load(object sender, EventArgs e) { StreamReader reader = new StreamReader(path); string json = reader.ReadToEnd(); reader.Close(); JObject obj = JObject.Parse(json); getAllProperties(obj); } void getAllProperties(JToken children) { TreeNode mainNode = treeView1.Nodes[0]; mainNode.Text = Path.GetFileNameWithoutExtension(path); foreach (JToken child in children.Children()) { var property = child as JProperty; if (property != null) { if (property.Value.Type == JTokenType.String) { TreeNode keyNode = mainNode.Nodes.Add(property.Name); keyNode.Nodes.Add(property.Value.ToString()); } if (property.Value.Type == JTokenType.Array) { JArray array = (JArray)property.Value; TreeNode node = mainNode.Nodes.Add(property.Name); for (int i = 0; i < array.Count; i++) { node.Nodes.Add(array[i].ToString()); } } if (property.Value.Type == JTokenType.Object) { TreeNode topNode = mainNode.Nodes.Add(property.Name.ToString()); foreach (var item in property) { if (item.Type == JTokenType.String) { if (property.Value.Type == JTokenType.String) { TreeNode keyNode = topNode.Nodes.Add(property.Name); keyNode.Nodes.Add(property.Value.ToString()); } if (property.Value.Type == JTokenType.Array) { JArray array = (JArray)property.Value; TreeNode node = topNode.Nodes.Add(property.Name); for (int i = 0; i < array.Count; i++) { node.Nodes.Add(array[i].ToString()); } } } } } // Console.WriteLine(property.Name + ":" + property.Value);//print all of the values } getAllProperties(child); } } } 

我试图得到父,但它没有名称和值属性:S。 有帮助吗? (抱歉语言错误)

问题在于,当递归下降JToken层次结构时,您还需要以递归方式下降正在创建的TreeNode层次结构,将子节点添加到刚刚创建的父节点,而不是根节点,沿着Recursion,解析xml将属性文件转换为treeview c# 。

因此,如果您这样做:

  private void Form1_Load(object sender, EventArgs e) { using (var reader = new StreamReader(path)) using (var jsonReader = new JsonTextReader(reader)) { var root = JToken.Load(jsonReader); DisplayTreeView(root, Path.GetFileNameWithoutExtension(path)); } } private void DisplayTreeView(JToken root, string rootName) { treeView1.BeginUpdate(); try { treeView1.Nodes.Clear(); var tNode = treeView1.Nodes[treeView1.Nodes.Add(new TreeNode(rootName))]; tNode.Tag = root; AddNode(root, tNode); treeView1.ExpandAll(); } finally { treeView1.EndUpdate(); } } private void AddNode(JToken token, TreeNode inTreeNode) { if (token == null) return; if (token is JValue) { var childNode = inTreeNode.Nodes[inTreeNode.Nodes.Add(new TreeNode(token.ToString()))]; childNode.Tag = token; } else if (token is JObject) { var obj = (JObject)token; foreach (var property in obj.Properties()) { var childNode = inTreeNode.Nodes[inTreeNode.Nodes.Add(new TreeNode(property.Name))]; childNode.Tag = property; AddNode(property.Value, childNode); } } else if (token is JArray) { var array = (JArray)token; for (int i = 0; i < array.Count; i++) { var childNode = inTreeNode.Nodes[inTreeNode.Nodes.Add(new TreeNode(i.ToString()))]; childNode.Tag = array[i]; AddNode(array[i], childNode); } } else { Debug.WriteLine(string.Format("{0} not implemented", token.Type)); // JConstructor, JRaw } } 

您将获得以下树视图结构:

在此处输入图像描述

这是我的解决方案。 输出与Notepad ++的JSTool插件相同: TreeView显示JSON

代码结构为TreeView扩展:

 using Newtonsoft.Json; using Newtonsoft.Json.Linq; using System.Collections.Generic; using System.Windows.Forms; namespace TestDLApp.Utilities.Extensions { public static class ObjectToTreeView { private sealed class IndexContainer { private int _n; public int Inc() => _n++; } private static void FillTreeView(TreeNode node, JToken tok, Stack s) { if (tok.Type == JTokenType.Object) { TreeNode n = node; if(tok.Parent != null) { if(tok.Parent.Type == JTokenType.Property) { n = node.Nodes.Add($"{((JProperty)tok.Parent).Name} <{tok.Type.ToString()}>"); } else { n = node.Nodes.Add($"[{s.Peek().Inc()}] <{tok.Type.ToString()}>"); } } s.Push(new IndexContainer()); foreach (var p in tok.Children()) { FillTreeView(n, p.Value, s); } s.Pop(); } else if (tok.Type == JTokenType.Array) { TreeNode n = node; if(tok.Parent != null) { if (tok.Parent.Type == JTokenType.Property) { n = node.Nodes.Add($"{((JProperty)tok.Parent).Name} <{tok.Type.ToString()}>"); } else { n = node.Nodes.Add($"[{s.Peek().Inc()}] <{tok.Type.ToString()}>"); } } s.Push(new IndexContainer()); foreach (var p in tok) { FillTreeView(n, p, s); } s.Pop(); } else { var name = string.Empty; var value = JsonConvert.SerializeObject(((JValue)tok).Value); if (tok.Parent.Type == JTokenType.Property) { name = $"{((JProperty)tok.Parent).Name} : {value}"; } else { name = $"[{s.Peek().Inc()}] : {value}"; } node.Nodes.Add(name); } } public static void SetObjectAsJson(this TreeView tv, T obj) { tv.BeginUpdate(); try { tv.Nodes.Clear(); var s = new Stack(); s.Push(new IndexContainer()); FillTreeView(tv.Nodes.Add("ROOT"), JsonConvert.DeserializeObject(JsonConvert.SerializeObject(obj)), s); s.Pop(); } finally { tv.EndUpdate(); } } } } 

您可以这样称呼它:

 treeView1.SetObjectAsJson(new MyNeatObject());