JSON转C# WinForms TreeView出现多余节点问题求助
问题:JSON转TreeView出现多余节点,无法匹配期望结构
我在查阅了大量JSON转TreeView的相关内容后,创建了指定的JSON数据,并编写了对应的C#代码。但运行后TreeView中出现了标记为1、2、3的多余节点,而我需要的是目标效果,已尝试3天仍未解决,请求帮助。
我的JSON数据
{ "Cars": { "Audi": [{ "A6 2.0 TDI quatro 2018 Red": ["S-Line", "17 inch rim", "Full sport packet"], "A5 1.6 TFSI 2018 Blue": ["Desing packet", "Sunroof"] }], "Mercedes-Benz": [{ "E220d AMG 2018 white": ["Glass ceiling", "Vacuum doors", "Navigation"], "E220d Exclusive Black 2018 Blue": ["Power seats", "Start & Stop"] }] } }
我的C#代码
private void Form1_Load(object sender, EventArgs e) { try { treeView1.Nodes.Clear(); var json = File.ReadAllText(Uz.path + @"cars.json"); var obj = JObject.Parse(json); var parent = Json2Tree(obj); treeView1.Nodes.Add(parent); treeView1.ExpandAll(); } catch (Exception ex) { MessageBox.Show(ex.Message, @"ERROR"); } } private static TreeNode Json2Tree(JObject obj) { //create the parent node var parent = new TreeNode(); //loop through the obj. all token should be pair<key, value> foreach (var token in obj) { //change the display Content of the parent parent.Text = token.Key; //create the child node var child = new TreeNode(); child.Text = token.Key; //check if the value is of type obj recall the method if (token.Value.Type.ToString() == "Object") { // child.Text = token.Key.ToString(); //create a new JObject using the the Token.value var o = (JObject)token.Value; //recall the method child = Json2Tree(o); //add the child to the parentNode parent.Nodes.Add(child); } //if type is of array else if (token.Value.Type.ToString() == "Array") { int ix = -1; // child.Text = token.Key.ToString(); //loop though the array foreach (var itm in token.Value) { //check if value is an Array of objects if (itm.Type.ToString() == "Object") { //child.Text = token.Key.ToString(); //call back the method ix++; var o = (JObject)itm; var objTN = Json2Tree(o); //objTN.Text = token.Key + "[" + ix + "]"; child.Nodes.Add(objTN); //parent.Nodes.Add(child); } //regular array string, int, etc else if (itm.Type.ToString() == "Array") { ix++; var dataArray = new TreeNode(); foreach (var data in itm) { //dataArray.Text = token.Key + "[" + ix + "]"; dataArray.Nodes.Add(data.ToString()); } child.Nodes.Add(dataArray); } else { child.Nodes.Add(itm.ToString()); } } parent.Nodes.Add(child); } else { //if token.Value is not nested // child.Text = token.Key.ToString(); //change the value into N/A if value == null or an empty string child.Nodes.Add(token.Value.ToString() == "" ? "N/A" : token.Value.ToString()); parent.Nodes.Add(child); } } return parent; }
当前效果与期望效果
- 当前效果:出现多余的1、2、3节点,层级不符合预期
- 期望效果:直接展示品牌→车型→配置的三层结构,无多余节点
解决方案
嘿,问题出在你的代码对JSON数组和嵌套对象的处理逻辑上!现在的代码会把数组本身当成一个节点,还错误地添加了索引标记,导致出现多余层级。咱们修改一下Json2Tree方法,让它正确解析你的JSON结构:
private void Form1_Load(object sender, EventArgs e) { try { treeView1.Nodes.Clear(); var json = File.ReadAllText(Uz.path + @"cars.json"); var obj = JObject.Parse(json); var parent = Json2Tree(obj); treeView1.Nodes.Add(parent); treeView1.ExpandAll(); } catch (Exception ex) { MessageBox.Show(ex.Message, @"ERROR"); } } private static TreeNode Json2Tree(JToken token) { // 处理对象类型(比如Cars、Audi下面的车型对象) if (token is JObject obj) { var parentNode = new TreeNode(); foreach (var prop in obj.Properties()) { parentNode.Text = prop.Name; var childNode = Json2Tree(prop.Value); // 如果子节点是数组处理后的节点集合,直接添加子节点的所有子项 if (childNode.Text == "__array_wrapper__") { foreach (TreeNode node in childNode.Nodes) { parentNode.Nodes.Add(node); } } else { parentNode.Nodes.Add(childNode); } } return parentNode; } // 处理数组类型(比如Audi下面的数组) else if (token is JArray array) { // 用一个临时节点包裹数组的子项,避免直接添加数组本身作为可见节点 var wrapperNode = new TreeNode("__array_wrapper__"); foreach (var item in array) { var itemNode = Json2Tree(item); wrapperNode.Nodes.Add(itemNode); } return wrapperNode; } // 处理数组中的字符串(配置项) else if (token is JValue value) { return new TreeNode(value.ToString()); } // 处理车型对象的属性(车型名称→配置数组) else if (token is JProperty prop) { var modelNode = new TreeNode(prop.Name); if (prop.Value is JArray configArray) { foreach (var config in configArray) { modelNode.Nodes.Add(new TreeNode(config.ToString())); } } return modelNode; } return new TreeNode("Unknown"); }
关键修改点说明:
- 支持多种JToken类型:把方法参数从
JObject改成JToken,这样能处理对象、数组、值等所有JSON元素 - 隐藏数组节点:用一个临时的"array_wrapper"节点包裹数组内容,然后在父节点中直接添加包裹节点的子项,避免数组本身显示为可见节点
- 直接解析车型与配置:当遇到车型名称对应的配置数组时,直接把配置项作为车型节点的子项,不需要额外层级
- 去掉多余索引标记:删除了所有添加索引的逻辑,让结构更简洁
这样修改后,TreeView就能直接展示Cars → Audi → 车型 → 配置的层级,和你期望的效果完全一致啦!
内容的提问来源于stack exchange,提问作者user1372430
相关产品推荐
相关产品推荐

