how to bind dynamic json into treeview wpf

后端 未结 2 1435
无人共我
无人共我 2020-12-03 02:27

I get JSON as follow:

explain format = json select...

Text is different depending on the type of operator select. How to bind dynamic JSON

2条回答
  •  失恋的感觉
    2020-12-03 02:41

    You can do this with the Json.NET framework. Json.NET has a static method JToken.Parse() (which is similar in purpose to XDocument.Parse()) and can turn a valid JSON string into a hierarchy of Newtonsoft.Json.Linq.JToken objects. This hierarchy can be bound into a WPF TreeView control using DataTemplate and HierarchicalDataTemplate to format data from all possible subclasses of JToken and iterate through their children.

    The concrete Json.NET JToken classes for which templates are required are:

    • JValue
    • JObject
    • JArray
    • JProperty
    • JConstructor
    • JRaw

    In order to bind a hierarchy of these classes into a tree, you first need a converter to convert the JToken.Children() method into a property:

    // Respectfully adapted from https://stackoverflow.com/questions/502250/bind-to-a-method-in-wpf/844946#844946
    
    public sealed class MethodToValueConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            var methodName = parameter as string;
            if (value == null || methodName == null)
                return null;
            var methodInfo = value.GetType().GetMethod(methodName, new Type[0]);
            if (methodInfo == null)
                return null;
            return methodInfo.Invoke(value, new object[0]);
        }
    
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotSupportedException(GetType().Name + " can only be used for one way conversion.");
        }
    }
    

    Having done this, an extremely simple XAML markup that can display this hierarchy in a tree is:

    
        
            
            
                
                
            
            
                
                    
                    
                
                        
            
                
                
                        
            
                
                
                        
            
                
                
                        
            
                
                    
                    
                
            
        
        
            
                
                    
                
            
        
    
    

    Then, when your user selects JSON data to view, you can do:

            var token = JToken.Parse(jsonString);
    
            var children = new List();
            if (token != null)
            {
                children.Add(token);
            }
    
            treeView1.ItemsSource = null;
            treeView1.Items.Clear();
            treeView1.ItemsSource = children;
    

    And the result looks like:

    enter image description here

    For the sample JSON:

    {
        ""id"": ""0001"",
        ""type"": ""donut"",
        ""name"": ""Cake"",
        ""ppu"": 0.55,
        ""batters"":
            {
                ""batter"":
                    [
                        { ""id"": ""1001"", ""type"": ""Regular"" },
                        { ""id"": ""1002"", ""type"": ""Chocolate"" },
                        { ""id"": ""1003"", ""type"": ""Blueberry"" },
                        { ""id"": ""1004"", ""type"": ""Devil's Food"" }
                    ]
            },
        ""topping"":
            [
                { ""id"": ""5001"", ""type"": ""None"" },
                { ""id"": ""5002"", ""type"": ""Glazed"" },
                { ""id"": ""5005"", ""type"": ""Sugar"" },
                { ""id"": ""5007"", ""type"": ""Powdered Sugar"" },
                { ""id"": ""5006"", ""type"": ""Chocolate with Sprinkles"" },
                { ""id"": ""5003"", ""type"": ""Chocolate"" },
                { ""id"": ""5004"", ""type"": ""Maple"" }
            ]
    }
    

    Of course, the user interface could be made more beautiful, e.g. by placing the value for JProperty tokens with only a single JValue child on the same row. However, this should give you an idea of how to do the binding.

    This approach binds the JSON to the tree directly. If you are looking for full editing functionality including adding, removing and renaming nodes, you may want to switch to a "Model-View-ViewModel" methodology in which the JToken hierarchy becomes the model and a lightweight view model handles modifications and notifications.

提交回复
热议问题