Load a TreeView from a tab-delimited file in C#

example

This example shows how to Load a TreeView from a tab-delimited file. When it starts, the program loads the following text file into its TreeView control.

Food
        Vegetables
                Beans
                Peas
                Lettuce
        Desserts
                Ice Cream
                Cookies
                        Peanut Butter Chip
                        Chocolate Chip
                Cake
        Fruit
                Bananas
                Peaches
Sports
        Volleyball
        Baseball

The following code shows how the program loads its TreeView control.

// Load a TreeView control from a file that uses tabs
// to show indentation.
private void LoadTreeViewFromFile(string file_name, TreeView trv)
{
    // Get the file's contents.
    string file_contents = File.ReadAllText(file_name);

    // Break the file into lines.
    string[] lines = file_contents.Split(
        new char[] {'\r', '\n'},
        StringSplitOptions.RemoveEmptyEntries);

    // Process the lines.
    trv.Nodes.Clear();
    Dictionary parents =
        new Dictionary();
    foreach (string text_line in lines)
    {
        // See how many tabs are at the start of the line.
        int level = text_line.Length -
            text_line.TrimStart('\t').Length;

        // Add the new node.
        if (level == 0)
            parents[level] = trv.Nodes.Add(text_line.Trim());
        else
            parents[level] =
                parents[level - 1].Nodes.Add(text_line.Trim());
        parents[level].EnsureVisible();
    }

    if (trv.Nodes.Count > 0) trv.Nodes[0].EnsureVisible();
}

First the program uses System.IO.File.ReadAllText to read the text file into a string. It then splits the file into lines using \r and \n characters as delimiters. It removes any blank lines, which may represent actual blank lines or may be due to the file containing \r\n combinations. (This is why the program doesn’t just use ReadAllLines. The Split method lets is easily remove blank lines but ReadAllLines doesn’t.)

Next the code clears the TreeView control and creates the parents dictionary to hold the most recent node at each level of the tree. For example, parents[2] will hold the most recently added node at level 2 in the tree. Later, if the program needs to add a node at level 3 of the tree, it can use parents[2] as its parent. Initially parents is empty.

The then code loops over the lines in the file. For each line, it counts the number of tab characters are at the beginning of the line to determine the node’s level in the tree. It does that by using Trim to remove leading tab characters and then subtracting the string’s new length from its original length.

Now the code creates a new node for the line. If the node is at level 0, the program adds it to the TreeView‘s Nodes collection to make it a top-level node. If the node is not at level 0, the code adds it as a child of the previously saved node at level - 1 in the tree, which was recorded in parents[level - 1]. In either case, the code saves the new node in parents[level] in case the program needs to add a node as a child of this one.

After adding the node, the program calls the node’s EnsureVisible method to make sure its parent is expanded.

After adding all of the nodes, the code ensures the first node is visible so the TreeView displays its top node if it is too long to show all of the nodes at the same time.


Download Example   Follow me on Twitter   RSS feed




This entry was posted in controls, files and tagged , , , , , , , , . Bookmark the permalink.

5 Responses to Load a TreeView from a tab-delimited file in C#

  1. Chris says:

    Hi Rod,

    I’m trying to use your above code but I keep getting a compile error:
    “Using the generic type ‘System.Collections.Generic.Dictionary’ requires 2 type arguments”

    I get that for the line:
    Dictionary parents = new Dictionary();

    Do you have any suggestions?

    • RodStephens says:

      Sorry. When the web site was converted to WordPress, it mangled a lot of code that includes brackets. That statement should be:

      Dictionary<int, TreeNode> parents =
          new Dictionary<int, TreeNode>();

      If you download the example program (for any of the site's examples), you can see the correct code without any web mangling.

  2. Barry says:

    Thanks Rod for posting your simple, elegant solution.** I’ve incorporated it into the GTK# (Linux) “outliner” app that I’m developing and I credited you for the logic. Nice going!
    ___

    ** You only need to retain as many past parents as there are levels in the tree and at any given level, a new node’s parent is always the most recent one saved. I was gonna use a stack until I saw your post. Thanks for saving me the brain twister — I’m getting too old for this shit. 😉

  3. this article save my life, i am undergraduate thesis now.
    i still can’t believe my parsing string algorithm works perfectly, i can create the parse tree representation under treeview control using this example.

    thanks for sharing, dear Rod Stephen.

  4. Joe says:

    Great, very helpful article. Thanks!

Leave a Reply

Your email address will not be published. Required fields are marked *