NodeEntryCollection无法获得子节点子节点

时间:2017-08-08 13:05:01

标签: c# dictionary nodes

根据此SO question提出建议,我通过路径数组填充列表视图,方法是将其转换为N odeEntryCollection

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

现在双击列表视图项目我正在使用它。

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);
            }
        }
    }
}

它在第一个目录上工作正常,我看到它的文件,但是当我再次双击子目录时,它会抛出:

  

[KeyNotFoundException未处理]   给定的密​​钥不在字典中。

enter image description here

1 个答案:

答案 0 :(得分:3)

假设根据问题path data to tree like data structure,您的NodeEntryCollection只是一个Dictionary<string, NodeEntry>,其中包含一些自定义项添加逻辑,其中NodeEntry本身就是string KeyNodeEntryCollection Children 1}}和NodeEntryCollection nodes

nodes.AddEntry("root", 0); nodes.AddEntry("root/main", 0); nodes.AddEntry("root/main/dev", 0); 是您的根节点。例如,用这种方式填写:

nodes

目前"root"只有一个元素Children"root"的{​​{1}}也是NodeEntryCollection,只有一个元素"main",依此类推。

您也可以通过迭代filesList来填充nodes。因此列表中仅显示root。当您双击它时,在此行中:

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

key值为"root",您成功获得了该集合中的第一个(也是单个)项。迭代Children后,main显示在列表中。一切都很好。

但是,当您点击main时,再次显示此foreachkey值为"main",但nodes只有"root" { {1}}密钥,显然会抛出KeyNotFoundException实际上,您需要遍历当前所选节点的Children,现在是"main",而不是您的根节点。

一种方法是跟踪当前选定的节点。

NodeEntryCollection viewRoot;

最初,例如在nodes填充时,将其设置为实际的树根节点:

viewRoot = nodes;

然后在你的事件处理程序中:

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);
        }
    }
}