0

Taking suggestion from this SO question, I'm populating a list view with paths array by converting it to NodeEntryCollection by

NodeEntryCollection nodes = new NodeEntryCollection();
foreach (string line in lines)
{
    nodes.AddEntry(line, 0);
}

Now on double click list view item I'm using this.

private void filesList_DoubleClick(object sender, EventArgs e)
{
    if (filesList.SelectedItems.Count == 0) return;

    if (filesList.SelectedItems[0].Tag.ToString() == "Folder")
    {
        string key = filesList.SelectedItems[0].Text;
        filesList.Clear();

        foreach (var item in nodes[key].Children) //Exception thrown here!
        {
            string fileName = Path.GetFileName(item.Key);
            string extension = Path.GetExtension(fileName);

            if (item.Value.Children.Count > 0)
            {
                ListViewItem itmNew = new ListViewItem(item.Key, 0);
                itmNew.Tag = "Folder";
                filesList.Items.Add(itmNew);

            }
            else
            {
                ListViewItem itmNew = new ListViewItem(item.Key, objIconListManager.AddFileIcon(fileName));
                itmNew.Tag = "File";
                filesList.Items.Add(itmNew);
            }
        }
    }
}

It works fine on first directory and I see files from it but when I double click again on a subdirectory it throws:

[KeyNotFoundException was unhandled] The given key was not present in the dictionary.

enter image description here

displayName
  • 13,888
  • 8
  • 60
  • 75
m.qayyum
  • 401
  • 2
  • 15
  • 44

1 Answers1

3

Assuming that according to the question path data to tree like data structure your NodeEntryCollection is just a Dictionary<string, NodeEntry> with a bit of custom item addition logic, where NodeEntry itself is the pair of string Key and NodeEntryCollection Children.

NodeEntryCollection nodes is your root node. For example, fill it this way:

nodes.AddEntry("root", 0);
nodes.AddEntry("root/main", 0);
nodes.AddEntry("root/main/dev", 0);

At the moment nodes has only single element "root". Children of "root" is also NodeEntryCollection with only single element "main" and so on.

Also you are probably filling the filesList by iterating nodes. So only root is displayed in the list. When you double-click it, in this line:

foreach (var item in nodes[key].Children)

key value is "root" and you successfully got a first (and single) item in the collection. After iterating through the Children the main is displayed in the list. Everything are okay.

However, when you doble-click main, you again go in this foreach and key value is "main", but nodes has only single "root" key, and obviously KeyNotFoundException will be thrown. Actually you need to iterate through the Children of the current selected node, which is "main" now, not your root node.

One way to do this is to track your current selected node.

NodeEntryCollection viewRoot;

Initially, for example at nodes filling, set it to you actual tree root node:

viewRoot = nodes;

Then in your event handler:

if (filesList.SelectedItems[0].Tag.ToString() == "Folder")
{
    string key = filesList.SelectedItems[0].Text;
    filesList.Clear();

    viewRoot = viewRoot[key].Children; // Set new view root

    //foreach (var item in nodes[key].Children) //Exception thrown here!
    foreach (var item in viewRoot) // iterate throught it
    {
        string fileName = Path.GetFileName(item.Key);
        string extension = Path.GetExtension(fileName);

        if (item.Value.Children.Count > 0)
        {
            ListViewItem itmNew = new ListViewItem(item.Key, 0);
            itmNew.Tag = "Folder";
            filesList.Items.Add(itmNew);

        }
        else
        {
            ListViewItem itmNew = new ListViewItem(item.Key, objIconListManager.AddFileIcon(fileName));
            itmNew.Tag = "File";
            filesList.Items.Add(itmNew);
        }
    }
}
Nina Lisitsinskaya
  • 1,818
  • 11
  • 18