• 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

    • Free Download Manager 6.28.1.6321 by Razvan Serea Free Download Manager is a powerful, easy-to-use and absolutely free download accelerator and manager. FDM accelerates downloads by splitting files into sections and then downloading them simultaneously. As a result download speed increases up to 600%, or even more! FDM can also resume broken downloads so you needn`t start downloading from the beginning after casual interruption. FDM lets you download files and whole web sites from any remote server via HTTP, HTTPS and FTP. You can also download files using BitTorrent protocol. In addition, Free Download Manager allows you to: adjust traffic usage; to organize and schedule downloads; download video from video sites; download whole web sites with HTML Spider; operate the program remotely, via the internet, and more! Free Download Manager is compatible with the most popular browsers Google Chrome, Firefox, Microsoft Edge, Internet Explorer and Safari. Free Download Manager 6.28.1.6321 changelog: Improved add-ons support. Improved M3U support. Fixed: crash bug in BitTorrent module. Fixed: minor bugs. Windows: a bit improved installer. Windows: Firefox bug workaround. Android: Qt updated to 6.9.1. Download: Free Download Manager (64-bit) | 45.8 MB (Freeware) Links: Home Page | Linux, Mac, Android | MS Store | Screenshot Get alerted to all of our Software updates on Twitter at @NeowinSoftware
    • Tariffs have nothing to do with this pricing. It was always intended to be slightly more expensive then the S25+
    • Hello, The static link still downloads 10.3.2040.0 from May 22, 2025. The 10.3.2412.0 version can be downloaded directly from emclient.com/dist/v10.3.2412/setup.msi. Regards, Aryeh Goretsky
    • Hello, Yes, and yes. More specifically, there are lots of features in Windows that I do not use--I cannot recall the last time I needed to run EUDCEDIT.EXE or ODBCAD32.EXE on a computer I own, but I'm sure that for some people they are useful, and for a smaller set of people they might even be indispensable. I don't begrudge Microsoft for including them as part of the standard Windows installation nor the people who need such tools; sometimes it is convenient to have some little utility or feature readily available. One thing I do begrudge is Microsoft's over-reliance on its own telemetry, and perhaps surpisingly on the flip side, customers who disable it. Collecting telemetry is generally a good thing, if it is done for good reasons and does not include any customer PII. However, how you interpret that telemetry is even more important, as that can lead to all sorts of disastrous decisions. On the customer side of things, telemetry is your "vote:" it's how you tell companies what features you use in the program, and lets them prioritize things appropriately. One glaring example is Windows 8, which shipped with the full-screen Start Screen because Microsoft's telemetry told them the average Windows user pressed the Windows key to bring up the Start Menu less than once a day. I have often wondered how many "power users" of previous versions of Windows (XP, Vista, and 7) that relied on the Start Menu disabled the telemetry that would have told Microsoft a difference story about its usage. More recently, I came across a young lady who had a problem with a third-party sync program on her computer running Windows 7. An update for the utility removed Windows 7 compatibility, and broke her backup process. Now, support for Windows 7 ended over 5 years ago in 2020, but there are ISVs who still support their software on it, but decisions about stuff like that are made, in part, by knowing what percentage of your customer base is on what operating system version. When I asked about that, she mentioned she had specifically disabled the telemetry from the sync program to its developers, which was optional to begin with. What made things even worse was that this was an open source utility, and its authors had a very clear, well-designed and scoped policy on the telemetry they collected, the pains they went through to avoid collecting any PII, and even other ancillary risks involving information disclosure (like just using of the software) because of the network connection made for the checks. Yet, she took herself out of telling the project maintainers "Hey, I use your software and I'm running Windows 7" by disabling the telemetry checks, which could have let them know they needed to continue supporting it. In a sense, sending telemetry is just like voting: Individually, you may not think it matters much, but it is often the basis for very important decisions. Regards, Aryeh Goretsky
    • Hello, My thoughts on this are mixed. Microsoft has hosted malicious code in the Microsoft Update Catalog where third party device drivers are stored; I wrote about one such incident about fifteen years ago, so if there are any other old malicious drivers floating around in the catalog, this will be a good step towards preventing any infestations from reoccurring. Another thing, which surprisingly is not mentioned in Microsoft's announcement, is that this helps protect against BYOVD (Bring Your Own Vulnerable Driver) attacks, where malware either comes with or downloads an older device drivers with vulnerabilities in it that can be exploited to gain access to kernel memory. Removing all those old device drivers from the Windows Update Catalog, potentially with all sorts of undisclosed vulnerabilities in them, means an attacker can no longer leisurely count on being able to download them from Microsoft's servers--something that may go unnoticed or ignored by security analysts. This makes the adversary attack a little more noisy, since they have to either include the device driver with the rest of their initial payload or download it from a third-party site at some point prior to beginning their BYOVD attack. On the other hand, it means that people who are looking for a specific version of an older device driver for whatever legitimate reasons, like compatibility, performance or stability, may end up going to dodgy third-party sites in search of older drivers, which increases the risk of exposure to everything from nuisance advertisements and unwanted software to actual malicious code. As for me, I have keeping copies of all the device drivers, firmware updates, etc. I have downloaded over the years, some dating back to DOS and Windows 3.x era, not just for hardware I won, but popular things like unified chipset and video card drivers, just in case I ever needed it. It might seem silly to collect such a thing, but the hardware drivers, firmware updates, and documentation are just about 2 TB in size. From my perspective, it is an inexpensive form of insurance, especially given that disk space is always getting cheaper over time. Regards, Aryeh Goretsky
  • Recent Achievements

    • Contributor
      GravityDead went up a rank
      Contributor
    • Week One Done
      BlakeBringer earned a badge
      Week One Done
    • Week One Done
      Helen Shafer earned a badge
      Week One Done
    • First Post
      emptyother earned a badge
      First Post
    • Week One Done
      Crunchy6 earned a badge
      Week One Done
  • Popular Contributors

    1. 1
      +primortal
      660
    2. 2
      ATLien_0
      266
    3. 3
      Michael Scrip
      235
    4. 4
      Steven P.
      164
    5. 5
      +FloatingFatMan
      149
  • Tell a friend

    Love Neowin? Tell a friend!