Creating tree view dynamically according to json text in Winforms

前端 未结 4 504
盖世英雄少女心
盖世英雄少女心 2020-12-15 01:47

I am building an application that gets in run-time JSON message from external source.

I don\'t know anything about the structure of the message text.

I want

相关标签:
4条回答
  • 2020-12-15 02:24

    Lots of questions there, really. If you really need guidance on every part of that then it's a lot to try and answer here.

    There are classes for reading JSON structures, readily available. As Yosi indirectly linked, there's JSON.net

    Once you can read the JSON, you can use it to construct the TreeView

    Editing is simple enough, as the TreeView has a property for LabelEdit that supports editing in-place. From there, it's just a matter of reacting to that and keeping track of the changes. Or perhaps reading it all back out in one fell swoop at the end, your choice. Either way, the TreeView has events such as BeforeLabelEdit, AfterLabelEdit, etc., all of which can be found on the TreeView link above.

    0 讨论(0)
  • 2020-12-15 02:26
     private void btn_Convert_MouseClick(object sender, MouseEventArgs e)
        {
            try
            {
                string json = rbt_display.Text;
                JObject obj = JObject.Parse(json);
                tvw_display.Nodes.Clear();
                TreeNode parent = Json2Tree(obj);
                parent.Text = "Root Object";
                tvw_display.Nodes.Add(parent);
    
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "ERROR");
            }
        }
    private TreeNode Json2Tree(JObject obj)
        {
            //create the parent node
            TreeNode 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.ToString();
                //create the child node
                TreeNode child = new TreeNode();
                child.Text = token.Key.ToString();
                //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
                    JObject 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")
                        {
                            TreeNode objTN = new TreeNode();
                            //child.Text = token.Key.ToString();
                            //call back the method
                            ix++;
    
                            JObject o = (JObject)itm;
                            objTN = Json2Tree(o);
                            objTN.Text = token.Key.ToString() + "[" + ix + "]";
                            child.Nodes.Add(objTN);
                            //parent.Nodes.Add(child);
                        }
                        //regular array string, int, etc
                        else if(itm.Type.ToString() == "Array")
                        {
                            ix++;
                            TreeNode dataArray = new TreeNode(); 
                            foreach (var data in itm)
                            {
                                dataArray.Text = token.Key.ToString() + "[" + 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 
                    if (token.Value.ToString() == "")
                        child.Nodes.Add("N/A");
                    else
                        child.Nodes.Add(token.Value.ToString());
                    parent.Nodes.Add(child);
                }
            }
            return parent;
    
        }
    sample json
    {
    "firstName": "John",
    "lastName": "Smith",
    "isAlive": true,
    "age": 25,
    "height_cm": 167.6,
    "address": {
    "streetAddress": "21 2nd Street",
    "city": "New York",
    "state": "NY",
    "postalCode": "10021-3100"
    },
    "phoneNumbers": [
    {
      "type": "home",
      "number": "212 555-1234"
    },
    {
      "type": "office",
      "number": "646 555-4567"
    }
    ],
    "children": [],
    "spouse": null
    }
    

    Note: This example uses NewtonSoft Json. Right-click solution and click manage NuGet packages to install the reference.

    0 讨论(0)
  • 2020-12-15 02:30

    This code will handle both JArray or JObject as an input:

            string jsonString = "your json string here";
            string rootName = "root", nodeName = "node";
            JContainer json;
            try {
                if (jsonString.StartsWith("["))
                {
                    json = JArray.Parse(jsonString);
                    treeView1.Nodes.Add(Utilities.Json2Tree((JArray)json, rootName, nodeName));
                }
                else
                {
                    json = JObject.Parse(jsonString);
                    treeView1.Nodes.Add(Utilities.Json2Tree((JObject)json, text));
                }
            }
            catch(JsonReaderException jre)
            {
                MessageBox.Show("Invalid Json.");
            }
    
    public class Utilities
    {
    
        public static TreeNode Json2Tree(JArray root, string rootName = "", string nodeName="")
        {
            TreeNode parent = new TreeNode(rootName);
            int index = 0;
    
            foreach(JToken obj in root)
            {
                TreeNode child = new TreeNode(string.Format("{0}[{1}]", nodeName, index++));
                foreach (KeyValuePair<string, JToken> token in (JObject)obj)
                {
                    switch (token.Value.Type)
                    {
                        case JTokenType.Array:
                        case JTokenType.Object:
                            child.Nodes.Add(Json2Tree((JObject)token.Value, token.Key));
                            break;
                        default:
                            child.Nodes.Add(GetChild(token));
                            break;
                    }
                }
                parent.Nodes.Add(child);
            }
    
            return parent;
        }
    
        public static TreeNode Json2Tree(JObject root, string text = "")
        {
            TreeNode parent = new TreeNode(text);
    
            foreach (KeyValuePair<string, JToken> token in root)
            {
    
                switch (token.Value.Type)
                {
                    case JTokenType.Object:
                        parent.Nodes.Add(Json2Tree((JObject)token.Value, token.Key));
                        break;
                    case JTokenType.Array:
                        int index = 0;
                        foreach(JToken element in (JArray)token.Value)
                        {
                            parent.Nodes.Add(Json2Tree((JObject)element, string.Format("{0}[{1}]", token.Key, index++)));
                        }
    
                        if (index == 0) parent.Nodes.Add(string.Format("{0}[ ]", token.Key)); //to handle empty arrays
                        break;
                    default:
                        parent.Nodes.Add(GetChild(token));
                        break;
                }
            }
    
            return parent;
        }
    
        private static TreeNode GetChild(KeyValuePair<string, JToken> token)
        {
            TreeNode child = new TreeNode(token.Key);
            child.Nodes.Add(string.IsNullOrEmpty(token.Value.ToString()) ? "n/a" : token.Value.ToString());
            return child;
        }
    
    }
    
    0 讨论(0)
  • 2020-12-15 02:37

    You can try this code :

    public class JsonTag
    {
        public JsonTag(JsonReader reader)
        {
            TokenType = reader.TokenType;
            Value = reader.Value;
            ValueType = reader.ValueType;
        }
    
        public JsonToken TokenType { get; set; }
        public object Value { get; set; }
        public Type ValueType { get; set; }
    }
    private void JsonToTreeview(string json)
    {
        tvwValue.BeginUpdate();
        var parentText = string.Empty;
    
        TreeNodeCollection parentNodes = tvwValue.Nodes;
        TreeNode current = null;
        tvwValue.Nodes.Clear();
        var reader = new JsonTextReader(new StringReader(json));
        while (reader.Read())
        {
            switch (reader.TokenType)
            {
                case JsonToken.None:
                    break;
                case JsonToken.StartObject:
                    current = new TreeNode("{}") { Tag = new JsonTag(reader) };
    
                    parentNodes.Add(current);
                    parentNodes = current.Nodes;
                    break;
                case JsonToken.StartArray:
                    current = new TreeNode("[]") { Tag = new JsonTag(reader) };
    
                    parentNodes.Add(current);
    
                    if (current.PrevNode != null)
                    {
                        if (((JsonTag)current.PrevNode.Tag).TokenType == JsonToken.PropertyName)
                            current.Parent.Text += "[]";
    
                        parentText = current.Parent.Text;
                        if (current.Parent.Parent.Text.Length > 2)
                            parentText = ", " + parentText;
                        current.Parent.Parent.Text = current.Parent.Parent.Text.Insert(current.Parent.Parent.Text.Length - 1, parentText);
                    }
    
                    parentNodes = current.Nodes;
                    break;
                case JsonToken.StartConstructor:
                    break;
                case JsonToken.PropertyName:
                    current = new TreeNode("\"" + reader.Value + "\" : ");
                    parentNodes.Add(current);
    
                    if (current.PrevNode != null)
                        current.PrevNode.Text += ",";
    
                    parentNodes = current.Nodes;
                    current = new TreeNode(reader.Value.ToString()) { Tag = new JsonTag(reader) };
                    parentNodes.Add(current);
    
                    break;
                case JsonToken.Comment:
                    break;
                case JsonToken.Raw:
                    break;
                case JsonToken.Date:
                case JsonToken.Integer:
                case JsonToken.Float:
                case JsonToken.Boolean:
                case JsonToken.String:
                    var readerValue = "";
                    if (reader.TokenType == JsonToken.String)
                        readerValue = "\"" + reader.Value + "\"";
                    else
                        readerValue = reader.Value.ToString();
    
                    current = new TreeNode(readerValue) { Tag = new JsonTag(reader) };
                    parentNodes.Add(current);
    
                    current.Parent.Text += readerValue;
    
                    parentText = current.Parent.Text;
                    if (current.Parent.Parent.Text.Length > 2)
                        parentText = ", " + parentText;
                    current.Parent.Parent.Text = current.Parent.Parent.Text.Insert(current.Parent.Parent.Text.Length - 1, parentText);
    
                    if (((JsonTag)current.PrevNode.Tag).TokenType == JsonToken.PropertyName)
                        current = current.Parent;
                    current = current.Parent;
                    parentNodes = current.Nodes;
                    break;
                case JsonToken.Bytes:
                    break;
                case JsonToken.Null:
                    break;
                case JsonToken.Undefined:
                    break;
                case JsonToken.EndObject:
                    if (current.FirstNode.Tag != null &&
                        ((JsonTag)current.FirstNode.Tag).TokenType == JsonToken.PropertyName)
                        current = current.Parent;
                    current = current.Parent;
                    if (current == null)
                        parentNodes = tvwValue.Nodes;
                    else
                        parentNodes = current.Nodes;
                    break;
                case JsonToken.EndArray:
                    if (((JsonTag)current.PrevNode.Tag).TokenType == JsonToken.PropertyName)
                        current = current.Parent;
                    current = current.Parent;
                    if (current == null)
                        parentNodes = tvwValue.Nodes;
                    else
                        parentNodes = current.Nodes;
                    break;
                case JsonToken.EndConstructor:
                    break;
                default:
                    throw new ArgumentOutOfRangeException();
            }
        }
        tvwValue.EndUpdate();
    }
    
    0 讨论(0)
提交回复
热议问题