• 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

    • LibreOffice 25.2.4 by Razvan Serea LibreOffice is the free power-packed Open Source personal productivity suite for Windows, Macintosh and Linux, that gives you six feature-rich applications for all your document production and data processing needs: Writer, Calc, Impress, Draw, Math and Base. Support and documentation is free from our large, dedicated community of users, contributors and developers. You, too, can also get involved! Choosing Between LibreOffice Still and LibreOffice Fresh: LibreOffice Still is a good choice if you value stability, a longer support cycle, and a more conservative approach to software updates. It's suitable for businesses and organizations where reliability and compatibility are crucial. LibreOffice Fresh is ideal if you're an enthusiast or an early adopter who wants to stay on the cutting edge of LibreOffice development and is willing to accept more frequent updates and occasional minor issues. Features: Writer is the word processor inside LibreOffice. Use it for everything, from dashing off a quick letter to producing an entire book with tables of contents, embedded illustrations, bibliographies and diagrams. The while-you-type auto-completion, auto-formatting and automatic spelling checking make difficult tasks easy (but are easy to disable if you prefer). Writer is powerful enough to tackle desktop publishing tasks such as creating multi-column newsletters and brochures. The only limit is your imagination. Calc tames your numbers and helps with difficult decisions when you're weighing the alternatives. Analyze your data with Calc and then use it to present your final output. Charts and analysis tools help bring transparency to your conclusions. A fully-integrated help system makes easier work of entering complex formulas. Add data from external databases such as SQL or Oracle, then sort and filter them to produce statistical analyses. Use the graphing functions to display large number of 2D and 3D graphics from 13 categories, including line, area, bar, pie, X-Y, and net - with the dozens of variations available, you're sure to find one that suits your project. Impress is the fastest and easiest way to create effective multimedia presentations. Stunning animation and sensational special effects help you convince your audience. Create presentations that look even more professional than the standard presentations you commonly see at work. Get your collegues' and bosses' attention by creating something a little bit different. Draw lets you build diagrams and sketches from scratch. A picture is worth a thousand words, so why not try something simple with box and line diagrams? Or else go further and easily build dynamic 3D illustrations and special effects. It's as simple or as powerful as you want it to be. Base is the database front-end of the LibreOffice suite. With Base, you can seamlessly integrate into your existing database structures. Based on imported and linked tables and queries from MySQL, PostgreSQL or Microsoft Access and many other data sources, you can build powerful databases containing forms, reports, views and queries. Full integration is possible with the in-built HSQL database. Math is a simple equation editor that lets you lay-out and display your mathematical, chemical, electrical or scientific equations quickly in standard written notation. Even the most-complex calculations can be understandable when displayed correctly. E=mc2. LibreOffice also comes configured with a PDF file creator, meaning you can distribute documents that you're sure can be opened and read by users of almost any computing device or operating system. LibreOffice also comes configured with a PDF file creator, meaning you can distribute documents that you're sure can be opened and read by users of almost any computing device or operating system. Download: LibreOffice 64-bit | LibreOffice 32-bit ~300.0 MB (Open Source) View: LibreOffice Website | Screenshot | Release Notes Get alerted to all of our Software updates on Twitter at @NeowinSoftware
    • I'm not sure why, but for some reason I think that if they are deciding to use the year for the version history they should use the whole year (i.e. iOS 2026).
    • Here's why it makes sense to name it iOS 26 and why it doesn't by Aditya Tiwari It has been almost 18 years since Apple launched the first version of its popular mobile operating system alongside the original iPhone. Recent reports and rumors circulating on the web suggest that the company is all set to unveil a major overhaul for iOS 19 at this year's WWDC keynote. There is something that baffled many when they found that the Cupertino giant is reportedly planning to rename iOS 19 to iOS 26. Yes, a company like Apple skipping eight versions for iOS is enough to leave users with a "why?" expression on their face. However, even if Apple pulls it off, there are two sides to the coin. Why it makes sense to call it iOS 26 There are several reasons why calling it iOS 26 instead of iOS 19 isn't as weird as it sounds. To begin with, it's something that has been done in the past. Samsung is a well-known example when we think about renaming device lineups and skipping version numbers. Samsung launched the Galaxy S20 series in 2020. But what was its predecessor? Galaxy S19? No, it was the Galaxy S10. The South Korean giant renamed its device lineup and aligned it with the year of launch, jumping ten versions in the process. So, someone viewing a Galaxy S23 can easily determine that the device was launched in 2023. It also gives them a feeling that they are using the 'latest and greatest' product. On the flip side, a device from the previous year may feel outdated, potentially motivating them to upgrade. Skipping version numbers isn't fun and games for everyone. Microsoft became the butt of jokes when it skipped Windows 9 and announced that Windows 8.1 will be upgraded to Windows 10 (that too in 2015). Windows 10 was thought to be "the last version of Windows", but things turned out differently. Apple's case would be a bit different, where the iOS version number is one year ahead. So, iOS 26 will release in 2025, iOS 27 in 2026, and so on. This approach is similar to how game companies like Electronic Arts name their gaming titles. Although it may seem off track, the naming scheme aligns with Apple's development schedule. The company typically announces new iOS versions at WWDC in June and rolls them out to the public in the fall season. After that, it continues to push incremental updates through the following year. In other words, a particular iOS version lives on your iPhone for a quarter of the launch year and about nine to ten months in the following year. Meanwhile, Samsung releases new Galaxy S devices at the start of the year, so it makes more sense to align their name with the current year. Not just iOS 26, reports said that Apple will streamline its confusing software naming system by renaming almost all of its operating systems to a single version. So, there will be iPadOS 26, macOS 26, tvOS 26, and watchOS 26 instead of iPadOS 19, macOS 16, tvOS 12, and so on. While the big move will make things easier for users, it will also highlight the work Apple has been doing to unify its software experience across devices. iOS and iPadOS have been related to each other from the beginning, but macOS gained ARM support in 2020 and began incorporating iOS-like UI elements. Apple has already developed a suite of Continuity features that enable different Apple devices to work together. macOS 14 Sonoma further bridged the gap between iPhone and Mac in 2023 with a revamped widgets picker UI, which allows access to and syncing with widgets stored on your iPhone. New widgets introduced in macOS 14 are interactive, similar to those on iPhone. They let you do stuff like checking off reminders, playing or pausing media, accessing smart home controls, and more. Apple's iOS 26/iOS 19 would be the second major naming shake-up in the history of iOS. The first one was when Apple renamed the operating system from iPhone OS to iOS in June 2010. iOS 26 is expected to be the biggest update in years, reportedly featuring a 'dramatic' glass-like UI overhaul, a revamped Camera app, live translation for AirPods, a new gaming app, and a new set of accessibility features. The glass-like design, first introduced on Apple's Vision Pro headset, is expected to make its way to tvOS and watchOS. Why doesn't it make sense to call it iOS 26 It already feels a bit awkward when you realize that the iPhone 16 runs iOS 18, for whatever reason, when the first iterations of both iPhone and iOS arrived in the same year. Adding eight more digits to the iOS version number will make it sound even weirder. The 19th generation of iPhone's operating system will be called iOS 26. Imagine buying an iPhone 17 later this year, and it runs iOS 26 out of the box. However, there are a couple of things Apple can do to tone down the awkwardness. Perhaps Apple can rename the iPhone series and start calling it iPhone 26 to match its software counterpart. A far-fetched and even more unlikely option is to drop version numbers from the iPhone's name entirely. Apple is already doing it for its tablets (iPad, iPad Pro, and iPad Air) and its Mac computers. Therefore, it won't be an issue once the users absorb the initial shock of the announcement. But we can't ignore that not having a version number tied to a product has its downsides. These are all speculations anyway. Whatever happens, Apple fans will get over it and learn to live with it, like they are living with the hopes of an upgraded Siri and AirPower to charge their Apple devices together.
    • I'd prefer the disclaimer being more transparent by putting it above the article.
    • dBpoweramp Music Converter 2025-06-05 by Razvan Serea Audio conversion perfected, effortlessly convert between formats. dBpoweramp contains a multitude of audio tools in one: CD Ripper, Music Converter, Batch Converter, ID Tag Editor and Windows audio shell enhancements. Preloaded with essential codecs (mp3, wave, FLAC, m4a, Apple Lossless, AIFF), additional codecs can be installed from [Codec Central], as well as Utility Codecs which perform actions on audio files. After 21 days the trial will end, reverting to dBpoweramp Free edition (learn the difference between Reference and dBpoweramp Free, here). dBpoweramp is compatible with Windows 10, 8, 7, Vista, both 32 and 64 bit. dBpoweramp Music Converter features: Convert audio files with elegant simplicity. mp3, mp4, m4a (iTunes / iPod), Windows Media Audio (WMA), Ogg Vorbis, AAC, Monkeys Audio, FLAC, Apple Lossless (ALAC) to name a few! Multi CPU Encoding Support Rip digitally record audio CDs (with CD Ripper) Batch Convert large numbers of files with 1 click Windows Integration popup info tips, audio properties, columns, edit ID-Tags DSP Effects such as Volume Normalize, or Graphic EQ [Power Pack Option] Command Line Encoding: invoke the encoder from the command line DSP Effects - process the audio with Volume Normalize, or Sample / Bit Rate Conversion, with over 30 effects dBpoweramp is a fully featured mp3 Converter dBpoweramp integrates into Windows Explorer, an mp3 converter that is as simple as right clicking on the source file >> Convert To. Popup info tips, Edit ID-Tags are all provided. dBpoweramp Music Converter 2025.06.05 changelog: Darkmode added Core Converter Debug log dumps ID Tags written VST Effect Folders dialog fixed missing InitCommonControls would not show correctly FLAC/Ogg/Opus/etc - allows editing of CDTOC ID Tag CD Ripper secure ripping log where shows TOC was not showing CD Extra correctly CD Ripper was incorrectly setting data track length on main display (for certain drives) CD Ripper internally better handling of corrupt TOCs CD TOC to Tag was incorrectly adding 150 to CD Extra disc CD Ripper shows "AccurateRip Unconfigured" in rip status rather than "not in accuraterip" if unconfigured CD Ripper art paste accepts https CueSheet added as standard - log file written to same folder as cue and folder.jpg AIFF internal code merge (macos >> windows) Download: dBpoweramp Music Converter R2025.06.05 | 82.2 MB (Shareware) View: dBpowerAMP Music Converter Website | Screenshot Get alerted to all of our Software updates on Twitter at @NeowinSoftware
  • Recent Achievements

    • Week One Done
      abortretryfail earned a badge
      Week One Done
    • First Post
      Mr bot earned a badge
      First Post
    • First Post
      Bkl211 earned a badge
      First Post
    • One Year In
      Mido gaber earned a badge
      One Year In
    • One Year In
      Vladimir Migunov earned a badge
      One Year In
  • Popular Contributors

    1. 1
      +primortal
      496
    2. 2
      snowy owl
      254
    3. 3
      +FloatingFatMan
      252
    4. 4
      ATLien_0
      228
    5. 5
      +Edouard
      192
  • Tell a friend

    Love Neowin? Tell a friend!