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

标签 c# json winforms treeview parent-child

我有一个winforms treeview,我可以自动读取数据,(一个节点等于key,里面的一个节点等于value),但是读取对象类型时,里面的值不会是对象节点的子节点(对象的键),(可能我没解释清楚,这是截图和我的方法。)

layer0 需要在纹理内部,比例需要在显示内部

layer0 needs to be inside textures and scale needs to be inside display

我的杰森:

{
"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, parsing xml file with attributes into 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
        }
    }

您将获得以下 TreeView 结构:

enter image description here

关于c# - 如何使用 JSON 数据递归填充 TreeView,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39673815/

相关文章:

c# - 使用 C# Windows 窗体应用程序(.NET Framework)进行 Windows Hello 验证?

c# - DotNet HighCharts ,用查询结果填充饼图

asp.net-mvc - return Json 将在指定 Url 时重定向到另一个 View

python - 除了请求库之外,如何使用 Python 脚本从 url 获取 json 数据?

c# - 使用带有进度报告的 C# 提取 ZipFile

c# - 如何在 C# 中使用 DbContext 删除对象?

c# - Entity Framework Core - 外键 1(额外的外键列)

java - 如何使用 Apache Camel XmlJsonDataFormat 编码将 XML 字符串转换为 JSON 字符串

c# - WinForms 中的计时器

c# - 背景 worker 。如何通过在 TreeView 中导航来显示当前进程?