• 0

C# and making a TreeView out of arrays


Question

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 :)

 

 

Recommended Posts

  • 0


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];

        }

  • 0

        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

 

  • 0

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()))
  • 0
  On 22/12/2013 at 14:17, Lant said:

 

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

  • 0

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.

  • 0
  On 22/12/2013 at 16:55, jakem1 said:

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.

  • 0
  On 22/12/2013 at 17:01, ka-la said:

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.

  • 0

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
  • 0
  On 26/12/2013 at 17:08, Andre S. said:

 

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)

  • 0
  On 27/12/2013 at 15:08, ka-la said:

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?

  • 0
        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

 

 

  • 0
  On 27/12/2013 at 22:59, ka-la said:

Sir I am truly thankful for your help, not sure how to return the regards :)

Glad to be of help. :) By the way, you can write this:

    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);

more simply as:

    var l_tree = new List<string[]> {
        new[] { "Example", "2", "1" },
        new[] { "Example", "2", "2" },
        new[] { "Example", "3", "0" }
    }
  • 0

I haven't tested but are you required to use the new[] syntax for the string arrays(i.e. string[]) in this example or can you get away with removing that part because of the string type?

  • 0
  On 28/12/2013 at 02:56, snaphat (Myles Landwehr) said:

I haven't tested but are you required to use the new[] syntax for the string arrays(i.e. string[]) in this example or can you get away with removing that part because of the string type?

new[] { "a", "b" }

 is shorthand (since C# 3.0) for :

new string[] { "a", "b" }

There's also a special case (which was just to copy C/C++ in C# 1.0) for assignment to a new variable, where you can omit everything:

string[] array = { "a", "b" }

But then you have to explicitely type the variable, you can't use var. IMO this is old fashioned and for consistency everyone should write:

var array = new[] { "a", "b" }

Of course this works for all types and not just string.

  • 0
  On 28/12/2013 at 03:12, Andre S. said:
new[] { "a", "b" }

 is shorthand (since C# 3.0) for :

new string[] { "a", "b" }

There's also a special case (which was just to copy C/C++ in C# 1.0) for assignment to a new variable, where you can omit everything:

string[] array = { "a", "b" }

But then you have to explicitely type the variable, you can't use var. IMO this is old fashioned and for consistency everyone should write:

var array = new[] { "a", "b" }

Of course this works for all types and not just string.

 

 

Right, right, Is the special case for assignment still possible in newer C# revisions or is is not-recommended/depreciated? I initially thought that you were being a bit more verbose with the new[] statement in the compound list assignment because it was required. Sounds like you were doing it more for consistencies sake; which is fair.

  • 0
  On 28/12/2013 at 03:28, snaphat (Myles Landwehr) said:

Right, right, Is the special case for assignment still possible in newer C# revisions or is is not-recommended/depreciated? I initially thought that you were being a bit more verbose with the new[] statement in the compound list assignment because it was required. Sounds like you were doing it more for consistencies sake; which is fair.

I'm doing it in the list assignment because it is and has always been required in that case. You can omit new[] only if you assign the array expression to an explicitely typed variable. This, in addition to the fact that this syntax contradicts the usual C# principle that every expression has a type, makes it inconsistent and confusing in my eyes, but it's still supported. It's only my opinion and not any sort of official deprecation or recommendation.

  • Like 1
  • 0
  On 28/12/2013 at 03:56, Andre S. said:

I'm doing it in the list assignment because it is and has always been required in that case. You can omit new[] only if you assign the array expression to an explicitely typed variable. This, in addition to the fact that this syntax contradicts the usual C# principle that every expression has a type, makes it inconsistent and confusing in my eyes, but it's still supported. It's only my opinion and not any sort of official deprecation or recommendation.

 

Fair enough, I'll say that the bolded text is a good reason to use it in the above code regardless of opinion ;-)

  • 0
  On 28/12/2013 at 04:09, snaphat (Myles Landwehr) said:

Fair enough, I'll say that the bolded text is a good reason to use it in the above code regardless of opinion ;-)

I'm not sure if we're talking past each other... this:

new List<string[]> {
     { "a", "b", "c" },
     { "b", "c", "d" }
}

is not and never was legal C#.

This topic is now closed to further replies.
  • Posts

    • Is Polaroid's Now 3rd Gen camera worth the $99.99 price drop? by Paul Hill For at least a decade there has been a nostalgic feeling gripping people in response to the digitization of everything. We’ve seen this mainly in products like vinyl, and even apps like Slowly that make you wait before your friends receive your “letter”. Another such product trying to capitalize on nostalgia is the Polaroid Now 3rd Generation camera. For a limited time, you can pick it up for just $99.99, instead of $119.99. If you are still searching for a gift for Father’s Day, taking advantage of this limited-time deal would be our suggestion. The Polaroid Now 3rd Generation is available in several colors but only four - Black, Coral, Purple, and Yellow - are available for $99.99, and they all look great. While there is certainly nothing wrong with snapping photos on your phone and storing them in the cloud, you do lose out on the tactileness of a photograph that you get with the Polaroid Now 3rd Generation. Additionally, in recent years, Google has been nagging everyone that their Google Photos storage is about to run out, urging you to delete photos or pay to upgrade, in future clean ups, you might accidentally delete a photo you really wanted to keep, you can’t do that as easily with hard-copy photograph. What it does (and doesn’t) With the 3rd generation of Polaroid Now, you get several improvements over the predecessor. There is a better light meter, upgraded two-lens autofocus, a built-in tripod mount, photo filter compatibility, a self-timer to take snaps with yourself included, and double-exposure modes. This camera remains faithful to the iconic Polaroid design but comes with new colors, four of which are now $99.99 for a limited time. Environmentalism has become all the rage in recent years and consumers want stuff that’s produced more responsibly; to this end, Polaroid has used 40% recycled materials to reduce waste and improve the product’s carbon footprint. The Polaroid Now 3rd Generation uses Polaroid i-Type Film and 600 Film, both of which are sold separately. The cost of the film is probably the biggest issue with this product, it’s priced at $17.99 per 8-pack, so you’re definitely going to want to be mindful about the shots you take. You can cut the cost by buying in bulk. Some of the reviewers were also disappointed with the low-light shots they took indoors. If you are planning to take indoor shots, then be mindful about what other people have said. Outdoors, everything seems in order. The two-lens autofocus system mentioned earlier is a key new feature of this camera. The system combines two fixed focus zones with one lens covering distances from 0.40 meters to 1.3 meters, and the other covering from 1.0 meter to infinity. The camera then automatically switches lenses depending on the best one for the shot. With the self-timer, you can now set up the Polaroid Now 3rd Generation on a tripod and join in with a group photo, or just take a shot of yourself. The double exposure feature lets you layer two images on one piece of film to bring out your creativity to create visually striking and unexpected results. How it compares At this discounted price, the Polaroid Now 3rd Generation is the same price as the 2nd Generation model, but gets newer features. It should also be stated that there’s a Polaroid Now+ 3rd Generation which you can connect to your phone to control with an app, but it’s priced higher. If you’re just looking for a camera that doesn’t complicate things, then the Polaroid Now 3rd Generation is the ideal model. You get the new hardware features, but don’t need to worry about extra connectivity. Who it’s right for The Polaroid Now 3rd Generation is ideal for casual photographers, those looking to snap memories to tangible film, gift-givers looking to buy a parent a Father’s Day gift, or those who love the classic Polaroid aesthetic and want it on a shelf somewhere for decorative purposes. While the camera is now priced well at $99.99, buyers need to consider the on-going cost of the film, which can add up. For anyone who hasn’t used a film camera before, it’s also important for me to point out that prints take a bit of time to develop, some users have also complained about the low-light performance when indoors. If you’re looking for snapping retro outdoor shots, the Polaroid Now 3rd Generation is definitely worth your consideration! Polaroid Now 3rd Generation (Black): $99.99 (Amazon US) - MSRP $119.99 / 17% off Polaroid Now 3rd Generation (Coral): $99.99 (Amazon US) - MSRP $119.99 / 17% off Polaroid Now 3rd Generation (Purple): $99.99 (Amazon US) - MSRP $119.99 / 17% off Polaroid Now 3rd Generation (Yellow): $99.99 (Amazon US) - MSRP $119.99 / 17% off This Amazon deal is US-specific and not available in other regions unless specified. If you don't like it or want to look at more options, check out the Amazon US deals page here. Get Prime (SNAP), Prime Video, Audible Plus or Kindle / Music Unlimited. Free for 30 days. As an Amazon Associate, we earn from qualifying purchases.
    • My Machines with Classic Outlook 365, have a banner on top Next Time Outlook is opened, will be autoly switched to NEW Outlook, not sure if i should try to prevent that or just get used to new Outlook at this point Probably gonna try to prevent that now that i read that privacy notice
    • Yeah, no. I won't be "upgrading" to the "mandatory" Windows 11 until all the bugs with DirectX and Hibernate are sorted out. Until then ASUS and Microsoft can both stuff it where the sun don't shine.
    • Microsoft Edge It works as expected, and I see no reason to use another browser.
    • Tech demos are a declaration of desire, an horizon for what they pretend to put on those boxes call consoles (i still laugh at the poor implementation of Hairworks in W3 when you compare it with the demos)...being made on UE5 doesn't give me any confidence considering how poorly it runs in those things, and CDPR is not a marvel in that aspect neither. And about the game, so far is non existent besides the cinematic trailer. If from the get go they have to justify the whys for the protagonist, you start your narrative with the left foot.
  • Recent Achievements

    • First Post
      m10d earned a badge
      First Post
    • Conversation Starter
      DarkShrunken earned a badge
      Conversation Starter
    • One Month Later
      jrromero17 earned a badge
      One Month Later
    • Week One Done
      jrromero17 earned a badge
      Week One Done
    • Conversation Starter
      johnwin1 earned a badge
      Conversation Starter
  • Popular Contributors

    1. 1
      +primortal
      251
    2. 2
      snowy owl
      157
    3. 3
      ATLien_0
      140
    4. 4
      +FloatingFatMan
      139
    5. 5
      Xenon
      128
  • Tell a friend

    Love Neowin? Tell a friend!