Bind Object to WPF TreeView

前端 未结 2 705
南方客
南方客 2021-01-14 10:02

I would like to know how to bind a custom data type to a TreeView.

The data type is basically an arraylist of objects that contain other arraylists. Ac

2条回答
  •  死守一世寂寞
    2021-01-14 10:24

    I lately had to deal with a similar issue and after much research was able to get to a good generic solution. My problem was a bit more generic: Visualize a .NET object's properties in a tree view. So given this class ```

    class Person
    {
      public string FirstName { get; set; }
      public string LastName { get; set; }
      public List Children { get; set; }
    }
    

    I should see a tree like for an example instance:

    - root
      - FirstName: John
      - LastName: Smith
      - Children:
        - [0]
          - FirstName: Ann
          - LastName: Smith
    

    ``` It's rather difficult to use reflection and go over an object's properties and such. Luckily, we already have a library that does that - Newtonsoft.Json. My trick is to serialize the object with Newtonsoft.Json, then deserialize with System.Web.Script.Serialization.JavaScriptSerializer.

    JavaScriptSerializer returns ArrayLists and Dictionaries, which are pretty simple to go over and add to the tree.

    Thanks to this article which gave me some of the concept ideas.

    Anyway, here's the entire code:

    In XAML:

    
        
            
                
                    
                        
                            
                            
                            
                        
                    
                
            
        
    
    

    In ViewModel:

    public IEnumerable TreeItemsSource
    {
        get
        {
            TreeNode tree = TreeNode.CreateTree(SelectedSession);
            return new List() { tree };
        }
    }
    

    And the TreeNode class

    public class TreeNode
    {
        public string Name { get; set; }
        public string Value { get; set; }
        public List Children { get; set; } = new List();
    
        public static TreeNode CreateTree(object obj)
        {
            JavaScriptSerializer jss = new JavaScriptSerializer();
            var serialized = Newtonsoft.Json.JsonConvert.SerializeObject(obj);
            Dictionary dic = jss.Deserialize>(serialized);
            var root = new TreeNode();
            root.Name = "session";
            BuildTree2(dic, root);
            return root;
        }
    
        private static void BuildTree2(object item, TreeNode node)
        {
            if (item is KeyValuePair)
            {
                KeyValuePair kv = (KeyValuePair)item;
                TreeNode keyValueNode = new TreeNode();
                keyValueNode.Name = kv.Key;
                keyValueNode.Value = GetValueAsString(kv.Value);
                node.Children.Add(keyValueNode);
                BuildTree2(kv.Value, keyValueNode);
            }
            else if (item is ArrayList)
            {
                ArrayList list = (ArrayList)item;
                int index = 0;
                foreach (object value in list)
                {
                    TreeNode arrayItem = new TreeNode();
                    arrayItem.Name = $"[{index}]";
                    arrayItem.Value = "";
                    node.Children.Add(arrayItem);
                    BuildTree2(value, arrayItem);
                    index++;
                }
            }
            else if (item is Dictionary)
            {
                Dictionary dictionary = (Dictionary)item;
                foreach (KeyValuePair d in dictionary)
                {
                    BuildTree2(d, node);
                }
            }
        }
    
        private static string GetValueAsString(object value)
        {
            if (value == null)
                return "null";
            var type = value.GetType();
            if (type.IsArray)
            {
                return "[]";
            }
    
            if (value is ArrayList)
            {
                var arr = value as ArrayList;
                return $"[{arr.Count}]";
            }
    
            if (type.IsGenericType)
            {
                return "{}";
            }
    
            return value.ToString();
        }
    
    }
    

提交回复
热议问题