Question

in my program the user is tagging a file with metadata he can select from a finite and already known number of boxes (suppose the boxes are Year, Month and Day). The file is then moved into a path which is created by combining the selected data.

I want the user to be able to specify in the program settings how the path is created through a string, something like

[ROOT] \ %year% \ %month% \ %day%

or any other combination of the three. He should be able to specify as many sublevels as he needs.

Now, I have a TreeView control where I want to display a preview of the general folder structure based on the configuration string the user has picked, whether that folder already exists or not.

I want every year folder to have all months subfolders, and every month subfolder to have all day subfolders (disregard actual day counts for the different months, it's just an example)

Right now I have lists holding the values for year, months and days, and a dictionary linking each list to the string with its name:

public partial class Form1 : Form
{
    string StructureString = @"year\month\day";
    string[] StructureArray = StructureString.Split(new char[] { '\\' }, StringSplitOptions.RemoveEmptyEntries);

    List<string> year = new List<string>() {"2014", "2013", "2012"};
    List<string> month = new List<string>() {"January", "February", ... , "December"};
    List<string> day = new List<string>() {"1", "2", ... , "31"};

    Dictionary<string, List<string>> StructureData = new Dictionary<string, List<string>>();
}

public Form1()
{
    InitializeComponent();  // Designer code
    InitializeData();
    PopulateTreeView();
}

private InitializeData()
{
    StructureData.Add("year", year);
    StructureData.Add("month", month);
    StructureData.Add("day", day);
}

Now, I know I have to use recursion here, and I already managed to have a TreeView which spidered through existing subdirectories in the file system. But I have no clue how to proceed here.

I am trying something like:

    int i = 0;

    private void PopulateTreeView()
    {
        treeView1.Nodes.Add(AddSubNode(i));
    }

    private TreeNode AddSubNode(int level)
    {
        TreeNode tn = new TreeNode();

        foreach (string s in StructureData[StructureArray[i]])
        {
          if (i < StructureArray.Length)
          {
              tn.Nodes.Add(AddSubNode(i + 1));
          }
        }
        i++;

        return tn;
    }

But I get a StackOverflowException. And, generally speaking, I am not even sure what I am coding here is making sense. Any help setting me in the right direction would be greatly appreciated.

Thank you!

Was it helpful?

Solution

Some user answered to my question and I managed to copy the code, before he deleted his own answer. There were some issues with it (a wrong variable name and - as pointed out by LarsTech - the nodes were blank) but I was able to tweak his solution and come up with the desired result.

I'm posting it as an answer for other people with the same issue.

private void PopulateTreeView()
{
    treeView1.Nodes.Add(AddSubNode(0, new TreeNode("Root")));
}

private TreeNode AddSubNode(int level, TreeNode hierarchy)
{
    if (level == StructureArray.Length)
    {
        return hierarchy;
    }

    foreach (string s in StructureData[StructureArray[i]])
    {
        tn.Nodes.Add(AddSubNode(level + 1, new TreeNode(s)));
    }
    return tn;
}

To customize the nodes attributes (text, tag, images...), instead of typing "new Treenode()" as a function argument, declare a TreeNode object in advance, then set its attributes and finally use it as a function argument.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top