Question

I have an input stream something like this:

John
Peter
Vanesa
Vanesa.New
Josh
Josh.New
Josh.New.Under
...

I need to Add Nodes to TreeView Someting like this:

+Customers
   +John
   +Peter
   +Vanesa
      +New
   +Josh
      +New
         +Under
 ...

I have an idea to split every string with parameter '.', but i have a problem with dynamicly loaded nodes. Maybe i have to use some kind of foreach...

I have old database table "group" with records id and GroupName. The are filled with these strings. I need to create some kind of "address" like: John.Element or Vanesa.New.Element or Josh.New.Under.Element, where Element is record from other datatable. The DB connection is not the problem, the problem is the dynamicly fill the tree

For now i have done adding strings that don't contains '.':

    reader = readGroups.ExecuteNonQuery();
    while(reader.Read())
    {
        string[] buff = reader.GetValue(1).ToString().Split('.');
        if (buff.Length == 1)
        {
            treeView1.Nodes[0].Nodes.Add(reader.GetValue(1));
        }
        else
        {
            //group contains '.'
        }
    }

EDIT: I have one more problem. There is records like this: John, John.New, John.Old, John.Older, John.Oldest ... So when the AddNodes() method runs, the foreach in the end of the method clears John.New, John.Old, John.Older nodes, but they got to go into the treenode John. If you have some idea...

Était-ce utile?

La solution

For winforms this is what you will need. I'm using recursion to add each child node inside each parent node. And I've made changes so that it will create a list of unique nodes before it starts adding any to the actual treeview

            internal class TreeNodeHierachy
    {
        public int Level { get; set; }
        public TreeNode Node { get; set; }
        public Guid Id { get; set; }
        public Guid ParentId { get; set; }
        public string RootText { get; set; }
    }

    private List<TreeNodeHierachy> overAllNodeList; 

    private void AddNodes(IEnumerable<string> data)
    {
        overAllNodeList = new List<TreeNodeHierachy>();
        foreach (var item in data)
        {
            var nodeList = new List<TreeNodeHierachy>();
            var split = item.Split('.');
            for (var i = 0; i < split.Count(); i++)
            {
                var guid = Guid.NewGuid();
                var parent = i == 0 ? null : nodeList.First(n => n.Level == i - 1);
                var root = i == 0 ? null : nodeList.First(n => n.Level == 0);
                nodeList.Add(new TreeNodeHierachy
                    {
                        Level = i,
                        Node = new TreeNode(split[i]) { Tag = guid },
                        Id = guid,
                        ParentId = parent != null ? parent.Id : Guid.Empty,
                        RootText = root != null ? root.RootText : split[i]
                    });
            }

            // figure out dups here
            if (!overAllNodeList.Any())
            {
                overAllNodeList.AddRange(nodeList);
            }
            else
            {
                nodeList = nodeList.OrderBy(x => x.Level).ToList();
                for (var i = 0; i < nodeList.Count; i++)
                {

                    var existingNode = overAllNodeList.FirstOrDefault(
                        n => n.Node.Text == nodeList[i].Node.Text && n.Level == nodeList[i].Level && n.RootText == nodeList[i].RootText);
                    if (existingNode != null && (i + 1) < nodeList.Count)
                    {

                        nodeList[i + 1].ParentId = existingNode.Id;
                    }
                    else
                    {
                        overAllNodeList.Add(nodeList[i]);
                    }
                }
            }
        }

        foreach (var treeNodeHierachy in overAllNodeList.Where(x => x.Level == 0))
        {
            treeView1.Nodes.Add(AddChildNodes(treeNodeHierachy));
        }
    }

    private TreeNode AddChildNodes(TreeNodeHierachy node)
    {
        var treeNode = node.Node;
        foreach (var treeNodeHierachy in overAllNodeList.Where(n => n.ParentId == node.Id))
        {
            treeNode.Nodes.Add(AddChildNodes(treeNodeHierachy));
        }
        return treeNode;
    }


    /// <summary>
    /// Handles the Click event of the button1 control.
    /// </summary>
    /// <param name="sender">The source of the event.</param>
    /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
    private void button1_Click(object sender, EventArgs e)
    {
        //SearchActiveDirectoryWithCriteria("(mailnickname=TM418)");

        var test = new List<string>
            {
                "John",
                "Peter",
                "Vanesa",
                "Vanesa.New",
                "Josh",
                "Josh.New",
                "Josh.New.Under",
                "Josh.Old"
            };

        AddNodes(test);           
    }

Autres conseils

This will probably do mainly what you want, you'll also need some xaml with a TreeView called treeView:

    public TreeViewItem root;

    public MainWindow()
    {
        InitializeComponent();

        root = new TreeViewItem
        {
            Header = "Customers"
        };

        treeView.Items.Add(root);

        addNode("John");
        addNode("Peter");
        addNode("Vanesa.New");
        addNode("Josh");
        addNode("Josh.New");
        addNode("Josh.New.Under");
    }

    private void addNode(string values)
    {
        var n = root;

        foreach (var val in values.Split('.'))
        {
            var isNew = true;

            foreach (var existingNode in n.Items)
            {
                if (((TreeViewItem)existingNode).Header.ToString() == val)
                {
                    n = (TreeViewItem)existingNode;
                    isNew = false;
                }
            }

            if (isNew)
            {
                var newNode = new TreeViewItem
                {
                    Header = val
                };

                n.Items.Add(newNode);

                n = newNode;
            }
        }
    }

I had the same problem. i solved that in this way:

defining a class that implement a tree:

class TreeBuilder
{
    public int index,depth;
    public string text;
    public Dictionary<string,TreeBuilder> childs;
    public void addToTreeVeiw(System.Windows.Forms.TreeNode root, TreeBuilder tb) {
        foreach (string key in tb.childs.Keys) {
            System.Windows.Forms.TreeNode t = root.Nodes.Add(tb.childs[key].text);
            addToTreeVeiw(t, tb.childs[key]);

        }
    }
}

and the main part:

string[] lis = {"a","b","a.a","a.ab","c","cc.a","a.b.dd","samad.hah.hoh"};
            treeView1.Nodes.Clear();
            TreeBuilder Troot = new TreeBuilder();
            TreeBuilder son;
            Troot.depth = 0;
            Troot.index = 0;
            Troot.text = "root";
            Troot.childs = new Dictionary<string, TreeBuilder>();

            foreach (string str in lis)
            {
                string[] seperated = str.Split('.');
                son = Troot;
                int index= 0;
                for (int depth = 0; depth < seperated.Length; depth++)
                {
                    if (son.childs.ContainsKey(seperated[depth]))
                    {
                        son = son.childs[seperated[depth]];
                    }
                    else {
                        son.childs.Add(seperated[depth],new TreeBuilder());
                        son = son.childs[seperated[depth]];
                        son.index= ++index;
                        son.depth = depth+1;
                        son.text = seperated[depth];
                        son.childs = new Dictionary<string, TreeBuilder>();
                    }
                }
            }
            treeView1.Nodes.Add("root");
            Troot.addToTreeVeiw(treeView1.Nodes[0], Troot);

I guess result is what you want:

enter image description here

Re @charles380 solution: I have updated the code to work with WPF .Net Core tree view.

public class TreeNodeHierarchy
    {
        public int Level { get; set; }
        public TreeViewItem Node { get; set; }
        public Guid Id { get; set; }
        public Guid ParentId { get; set; }
        public string RootText { get; set; }
    }
    public class TreeManager{

        public List<TreeNodeHierarchy> overAllNodeList;

        public void AddNodes(IEnumerable<string> data, ref TreeView treeView1)
        {
            overAllNodeList = new List<TreeNodeHierarchy>();
            foreach (var item in data)
            {
                //\test
                var nodeList = new List<TreeNodeHierarchy>();
                var split = item.Split('.', StringSplitOptions.RemoveEmptyEntries);
                for (var i = 0; i < split.Count(); i++)
                {
                    var guid = Guid.NewGuid();
                    var parent = i == 0 ? null : nodeList.First(n => n.Level == i - 1);
                    var root = i == 0 ? null : nodeList.First(n => n.Level == 0);
                    nodeList.Add(new TreeNodeHierarchy
                    {
                        Level = i,
                        Node = new TreeViewItem { Header = split[i],   Tag = guid },
                        Id = guid,
                        ParentId = parent != null ? parent.Id : Guid.Empty,
                        RootText = root != null ? root.RootText : split[i]
                    });
                }

                // figure out dups here
                if (!overAllNodeList.Any())
                {
                    overAllNodeList.AddRange(nodeList);
                }
                else
                {
                    nodeList = nodeList.OrderBy(x => x.Level).ToList();
                    for (var i = 0; i < nodeList.Count; i++)
                    {

                        var existingNode = overAllNodeList.FirstOrDefault(
                            n => n.Node.Header.ToString() == nodeList[i].Node.Header.ToString() && n.Level == nodeList[i].Level && n.RootText == nodeList[i].RootText);


                        if (existingNode != null && (i + 1) < nodeList.Count)
                        {

                            nodeList[i + 1].ParentId = existingNode.Id;
                        }
                        else
                        {
                            overAllNodeList.Add(nodeList[i]);
                        }
                    }
                }
            }

            foreach (var treeNodeHierachy in overAllNodeList.Where(x => x.Level == 0))
            {
                treeView1.Items.Add(AddChildNodes(treeNodeHierachy));
            }
        }

        private TreeViewItem AddChildNodes(TreeNodeHierarchy node)
        {
            var treeNode = node.Node;
            foreach (var treeNodeHierachy in overAllNodeList.Where(n => n.ParentId == node.Id))
            {
                treeNode.Items.Add(AddChildNodes(treeNodeHierachy));
            }
            return treeNode;
        }
    }
}

Sample calling code:

    var lstFolders= new List<string>
            {
                "John",
                "Peter",
                "Vanesa",
                "Vanesa.New",
                "Josh",
                "Josh.New",
                "Josh.New.Under",
                "Josh.Old"
            };
TreeManager treeManager = new TreeManager();
treeManager.AddNodes(lstFolders, ref tr);
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top