根据此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未处理] 给定的密钥不在字典中。
答案 0 :(得分:3)
假设根据问题path data to tree like data structure,您的NodeEntryCollection
只是一个Dictionary<string, NodeEntry>
,其中包含一些自定义项添加逻辑,其中NodeEntry
本身就是string Key
对NodeEntryCollection 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
时,再次显示此foreach
且key
值为"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);
}
}
}