Jump to content



Photo

C# and making a TreeView out of arrays

Answered Go to the full post c#

  • Please log in to reply
26 replies to this topic

#1 ka-la

ka-la

    Neowinian

  • Joined: 24-October 12

Posted 22 December 2013 - 13:52

So I have encountered a probleem while trying to populate a TreeView control with nodes. I hope that there are a some kind people who täke the time and help me figuure out a correct solution.

So lets say I have 3 arrays:

 

["Example", "2", "1"]

{"Example", "2", "2"]

["Example", "3", "0"]

 

I know that my arrays have always exactly 3 elements in them, so the treeview will never have more than 3 childnodes

 

But all I am able to get is

 

Example

 2

  1

Example

 2

  2

Example

 3

  0

 

But the goal would be:

 

Example

 2

  1

  2

 3

  0

 

So where would I start chasing down the answer to my probleem?
Big thanks in advance :)

 

 



Best Answer Andre S. , 27 December 2013 - 22:42

        void InitTreeView(List<string[]> arrays) {
            foreach (var array in arrays) {
                AddArray(array, 0, m_treeView.Nodes);
            }
        }


        /// <summary>
        /// Recursively adds each element of the array to the tree
        /// </summary>
        void AddArray(string[] array, int index, TreeNodeCollection nodes) {
            // Termination condition: we've past the bounds of the array
            if (index < array.Length) {
                var nextNode = AddValue(array[index], nodes);
                AddArray(array, index + 1, nextNode.Nodes);
            }
        }


        /// <summary>
        /// If the value exists, returns it, otherwise creates a new value
        /// </summary>
        TreeNode AddValue(string value, TreeNodeCollection nodes) {
            var index = nodes.IndexOfKey(value);
            if (index == -1) {
                var newNode = new TreeNode(value) { Name = value };
                nodes.Add(newNode);
                return newNode;
            }
            return nodes[index];
        }
Go to the full post



#2 Eric

Eric

    Neowinian Senior

  • Tech Issues Solved: 12
  • Joined: 02-August 06
  • Location: Greenville, SC

Posted 22 December 2013 - 14:14

What have you worked out so far? We need something to start at. :)

#3 OP ka-la

ka-la

    Neowinian

  • Joined: 24-October 12

Posted 22 December 2013 - 14:16

        private static TreeView GetTree(TreeView Tree, List<string[]> Items)
        {
            foreach (string[] item in Items)
            {
                TreeNode parent = new TreeNode();
                parent.Text = item[0];
                TreeNode child = new TreeNode();
                child.Text = item[1];
                TreeNode child2 = new TreeNode();
                child2.Text = item[2];
                child.Nodes.Add(child2);
                parent.Nodes.Add(child);
                Tree.Nodes.Add(parent);
            }
            return Tree;
        }

Well, I have a code  that goes through each array and creates parentnode with array first item, childnode with second and childnode of childnode with third. So thats pretty basic approach

 



#4 Lant

Lant

    Neowinian Senior

  • Joined: 13-April 06

Posted 22 December 2013 - 14:17

I imagine you want to do something like the following pseudo code.
Idea is that you create the array of children you want before you create the treenode with the label.

tv = new TreeView();
dict = new Dictionary<String, List<String>>();
arrs = array of those arrays;

for arr in arrs:
     dict[arr[1]].Add(arr[2]);

for (key, value) in dict:
    tv.Nodes.Add(new TreeNode(key, value.ToArray()))


#5 OP ka-la

ka-la

    Neowinian

  • Joined: 24-October 12

Posted 22 December 2013 - 14:47

 

I imagine you want to do something like the following pseudo code.
Idea is that you create the array of children you want before you create the treenode with the label.
 

 

Got lost trying to implement something like that, although the approach is right, I need to create the last level nodes first



#6 Lant

Lant

    Neowinian Senior

  • Joined: 13-April 06

Posted 22 December 2013 - 15:13

Got lost trying to implement something like that, although the approach is right, I need to create the last level nodes first

 If you provide the code you have, we can see what needs to be changed to fix it.



#7 _dandy_

_dandy_

    Neowinian Senior

  • Joined: 07-May 04

Posted 22 December 2013 - 15:13

What sort of performance are you looking for?  If you're just talking a few hundred items, then try this approach.

 

Each node should be identifiable via a predictable, unique key of your creation (it could be, literally, the value you're trying to insert).  Try to find your parent node by looking for the key it should have.  If you can't find it, create a new node and insert it.  If it returns something instead, then use that as the parent of the key you're trying to insert.



#8 jakem1

jakem1

    Neowinian Senior

  • Tech Issues Solved: 2
  • Joined: 17-November 06

Posted 22 December 2013 - 16:55

Try a recursive function.

#9 OP ka-la

ka-la

    Neowinian

  • Joined: 24-October 12

Posted 22 December 2013 - 17:01

Try a recursive function.

This is the right way to go, I know that, but I am totally unsure how the code should look like.

Regarding to performance, it is important in my case since we're talking about thousands of nodes here.



#10 +snaphat (Myles Landwehr)

snaphat (Myles Landwehr)

    Electrical & Computer Engineer

  • Tech Issues Solved: 29
  • Joined: 23-August 05
  • OS: Win/Lin/Bsd/Osx
  • Phone: dumb phone

Posted 22 December 2013 - 18:47

This is the right way to go, I know that, but I am totally unsure how the code should look like.

Regarding to performance, it is important in my case since we're talking about thousands of nodes here.

 

As a general rule of thumb, if you find yourself pushing program state into some sort of explicit stack when using an iterative solution (pushing state to a queue for example): you are may just be doing an explicit recursion (what I mean by this is that you are doing the same work that a recursion would do for you) and are may be better suited to just use a recursive solution.



#11 Andre S.

Andre S.

    Asik

  • Tech Issues Solved: 10
  • Joined: 26-October 05

Posted 26 December 2013 - 17:08

This should be very straightforward to convert to C#, but here's the general idea for a recursive solution:

InitTreeView:
    var data = new List<string[]> { " Your data here " };
    foreach array in data:
        AddArray(array, 0, root collection)

AddArray(array, index, nodes):
    // Termination condition: index is past the end of the array
    // Otherwise:
    nextNode = AddValue(array[index], nodes)
    AddArray(array, index + 1, nextNode collection)

AddValue(value, nodes):
    // If node exists in the collection, return it
    // Otherwise create new node with the value, add it and return it


#12 Snake89

Snake89

    Neowinian

  • Joined: 16-July 04

Posted 26 December 2013 - 17:54

Here's a really good link for what you need:

http://www.c-sharpco...viewBasics.aspx



#13 OP ka-la

ka-la

    Neowinian

  • Joined: 24-October 12

Posted 27 December 2013 - 15:08

 

This should be very straightforward to convert to C#, but here's the general idea for a recursive solution:


InitTreeView:
    var data = new List<string[]> { " Your data here " };
    foreach array in data:
        AddArray(array, 0, root collection)

AddArray(array, index, nodes):
    // Termination condition: index is past the end of the array
    // Otherwise:
    nextNode = AddValue(array[index], nodes)
    AddArray(array[index], index + 1, nextNode collection)

AddValue(value, nodes):
    // If node exists in the collection, return it
    // Otherwise create new node with the value, add it and return it

Some parts of the code still remain as a puzzle for me:
1)  What should AddValue return, a collection or a treenode?

2) AddArray( array[index].... seems weird to me, it expects an array, but your code sends it a value from array with that index

3) What should AddArray return? my best guess so far is, it is just a void and does not return anything.

4) nextNode collection should be nextNode.Nodes ? (case the AddValue returns a treenode)



#14 Andre S.

Andre S.

    Asik

  • Tech Issues Solved: 10
  • Joined: 26-October 05

Posted 27 December 2013 - 18:46

Some parts of the code still remain as a puzzle for me:

1)  What should AddValue return, a collection or a treenode?

2) AddArray( array[index].... seems weird to me, it expects an array, but your code sends it a value from array with that index

3) What should AddArray return? my best guess so far is, it is just a void and does not return anything.

4) nextNode collection should be nextNode.Nodes ? (case the AddValue returns a treenode)

1) As I wrote it, it returns a TreeNode. You could just return the collection as well as that's the only thing AddArray needs.

2) Oops that was a mistake, fixed. Should pass array.

3) AddArray is void.

4) Yup.

 

Is this homework?



#15 OP ka-la

ka-la

    Neowinian

  • Joined: 24-October 12

Posted 27 December 2013 - 18:51

        private static TreeView GetTree(TreeView Tree)
        {
            Tree.BeginUpdate();
            List<string[]> l_tree = new List<string[]>();
            string[] str1 = new string[] {"Example", "2", "1"};
            string[] str2 = new string[] { "Example", "2", "2"};
            string[] str3 = new string[] { "Example", "3", "0" };
            l_tree.Add(str1);
            l_tree.Add(str2);
            l_tree.Add(str3);

            foreach (string[] array in l_tree)
            {
                AddArray(array, 0, Tree.Nodes);
            }
            Tree.EndUpdate();
            return Tree;
        }

        private static void AddArray(string[] array, int index, TreeNodeCollection nodes)
        {
            if (index < 3)
            {
                var nextNode = AddValue(array[index], nodes);
                AddArray(array, index + 1, nextNode.Nodes);
            }
        }

        private static TreeNode AddValue(string value, TreeNodeCollection nodes)
        {
            if (nodes.Count == 0)
            {
                TreeNode newnode = new TreeNode();
                newnode.Text = value;
                nodes.Add(newnode);
                return newnode;
            }
            else
            {
                foreach (TreeNode node in nodes)
                {
                    if (node.Text == value)
                    {
                        return node;
                    }
                    else
                    {
                        TreeNode newnode = new TreeNode();
                        newnode.Text = value;
                        node.Nodes.Add(newnode);
                        return node;
                    }
                }
            }
            return null;
        }

If the initial tree is empty, I get nullreferenceexception, since I cant go through the empty collection in addvalue

Example

 2

  1

    2

    0

  3