【问题标题】:C# - How to map object structure to a TreeView?C# - 如何将对象结构映射到 TreeView?
【发布时间】:2016-12-27 09:01:32
【问题描述】:

我想将对象的结构映射到 TreeView。对象本身由Dictionary<string,object> 组成。我现在的问题是结构的深度没有一致性,因为每个object 都可以是另一个字典(或只是一个文本)。例如,这是一个对象的样子:

我知道我需要某种递归,但我不确定如何将其映射到树视图? 这是我当前的代码:

        Dictionary<string, object> dict = (Dictionary<string, object>)e.Node.Tag; //dict is the object
        foreach(KeyValuePair<string,object> kvp in dict)
        {
            if(kvp.Key != "icon" && kvp.Key != "typeLine")
            {

            }
        }

非常感谢任何帮助!

编辑:有时 KeyValuePair 的对象不是另一个字典,而只是一个对象数组(我不知道为什么会这样)。至少在我看来,将这种奇怪的数据组合映射到树视图是不可能的。这是一张关于我的意思的图片:

Edit(2):好的,我想我终于可以使用 Matthys 的这个稍微修改过的函数了:

        private TreeNode[] RecurseTree(Dictionary<string, object> dic)
    {
        List<TreeNode> branch = new List<TreeNode>();

        foreach (KeyValuePair<string, object> kvp in dic)
        {
            TreeNode twig = new TreeNode(kvp.Key);
            if (kvp.Value is string || kvp.Value is bool || kvp.Value is int)
            {
                twig.Nodes.Add(new TreeNode(kvp.Value.ToString()));
            }
            else if (kvp.Value is Dictionary<string, object>)
            {
                twig.Nodes.AddRange(RecurseTree((Dictionary<string, object>)kvp.Value));
            }
            else
            {
                IEnumerable enumerable = (kvp.Value as IEnumerable);
                if (enumerable != null)
                {
                    foreach (var item in enumerable)
                    {
                        if (item is string || item is bool || item is int)
                        {
                            twig.Nodes.Add(new TreeNode(item.ToString()));
                        }
                        else if (item is Dictionary<string, object>)
                        {
                            twig.Nodes.AddRange(RecurseTree((Dictionary<string, object>)item));
                        }
                        else
                        {
                            IEnumerable en = (item as IEnumerable);
                            foreach(var i in en)
                                twig.Nodes.Add(new TreeNode(i.ToString()));
                        }
                    }
                }
            }
            branch.Add(twig);
        }

        return branch.ToArray();
    }

【问题讨论】:

    标签: c# recursion treeview


    【解决方案1】:

    试试这样的:

    private TreeNode[] RecurseTree(Dictionary<string, object> dic)
    {
        List<TreeNode> branch = new List<TreeNode>();
    
        foreach (KeyValuePair<string, object> kvp in dic)
        {
            TreeNode twig = new TreeNode(kvp.Key);
            if (kvp.Value is string)
            {
                twig.Nodes.Add(new TreeNode(kvp.Value.ToString()));
            }
            else if (kvp.Value is Dictionary<string, object>)
            {
                twig.Nodes.AddRange(RecurseTree((Dictionary<string, object>)kvp.Value));
            }
            else
            {
                IEnumerable enumerable = (kvp.Value as IEnumerable);
                if(enumerable != null)
                {
                    foreach(var item in enumerable)
                    {
                        if (item is string)
                        {
                            twig.Nodes.Add(new TreeNode(item.ToString()));
                        }
                        else if (item is Dictionary<string,object>)
                        {
                            twig.Nodes.AddRange(RecurseTree((Dictionary<string, object>)item));
                        }
                    }
                }
            }
            branch.Add(twig);
        }
    
        return branch.ToArray();
    }
    

    然后这样称呼它:

     treeView1.Nodes.AddRange(RecurseTree(YourDictionaryObject));
    

    我测试了这段代码如下:

            Dictionary<string, object> a = new Dictionary<string, object>();
            Dictionary<string, object> b = new Dictionary<string, object>();
            Dictionary<string, object> c = new Dictionary<string, object>();
            Dictionary<string, object> d = new Dictionary<string, object>();
            Dictionary<string, object> h = new Dictionary<string, object>();
            Dictionary<string, object> f = new Dictionary<string, object>();
            Dictionary<string, object> g = new Dictionary<string, object>();
            Dictionary<string, object> i = new Dictionary<string, object>();
            object[] arrayOfObjects = {"This","is","an","array","of","objects", i};
    
            object u, v, w, x, y, z;
            u = "string u";
            w = "string w";
            v = "string v";
            x = "string x";
            y = "string y";
            z = "string z";
    
            i.Add("i1",u);
            h.Add("h2", arrayOfObjects);
            h.Add("h1", y);
            d.Add("d2", h);
            d.Add("d1", x);
            c.Add("c1", w);
            b.Add("b1", c);
            b.Add("b2", v);
            b.Add("b3", d);
            a.Add("a1", b);
            a.Add("a2", z);
    
            treeView1.Nodes.AddRange(RecurseTree(a));
    

    这是结果:

    【讨论】:

    • 非常感谢,这解决了我的很多问题(但遗憾的是不是全部)。我在我的问题中添加了更多细节。如果您能再看一遍,我将不胜感激。
    • 我更新了答案,希望我理解你正确。您可能还需要添加某种检查以确保对象公开 ToString() 方法,以便在遇到无法显示为字符串的对象时它不会中断。
    • 再次编辑了答案,您的对象数组现在也支持 Dictionary 的对象。然而,尚不支持在数组中添加数组,但很容易添加。
    • 好的,我们现在非常接近,但还没有完全到达。但是我不知道如何才能更好地描述它,您已经为我做了很多工作,非常感谢,我真的很感激。伙计,我讨厌数据的组织方式。
    • 好的,我认为现在一切正常。我用附加到我最初问题的代码修复了它。非常感谢!
    【解决方案2】:

    如果我理解得很好,您的问题只是在TreeView 中插入一个KeyValuePair 的键和一个值。您想添加一个表示键并包含值的项目吗?如果是这样,下面是在 TreeView 中插入包含其他项目的项目的代码:

    yourTreeView.Nodes.Add(kvp.Key);
    yourTreeView.Nodes[yourTreeView.Nodes.Count - 1].Nodes.Add(kvp.Value);
    


    编辑:

    如果是这样,您的问题是kvp.Value 不是string,而是object,您可以使用ToString() 方法:

    yourTreeView.Nodes.Add(kvp.Key);
    yourTreeView.Nodes[yourTreeView.Nodes.Count - 1].Nodes.Add(kvp.Value.ToString());
    

    如果ToString() 没有返回具有正确格式的字符串,那么您别无选择,只能创建自己的方法(更好的扩展方法)来返回对象的正确表示:

    public static class Extensions
    {
    
        [System.Diagnostics.DebuggerHidden]
        public static string AsString(this object obj)
        {
            return "Your correct string representation.";
        }
    }
    

    【讨论】:

    • 这不起作用,因为kvp.value 不是字符串而是对象。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-06-27
    • 1970-01-01
    • 2012-04-16
    • 2010-09-10
    • 1970-01-01
    • 2021-02-11
    • 2018-04-02
    相关资源
    最近更新 更多