关于目录树的困惑
本文关键字:目录树 | 更新日期: 2023-09-27 18:32:27
我正在尝试列出计算机中的所有文件。下面的这段代码符合我的期望。我的计算机 C 和 D 中有两个驱动器。如果用户选择 D 驱动器,则一切正常。但是当选择C驱动器(不是子文件夹之一)应用程序没有响应时。
private void ListDirectory(TreeView treeView, string path)
{
treeView.Nodes.Clear();
var rootDirectoryInfo = new DirectoryInfo(path);
treeView.Nodes.Add(CreateDirectoryNode(rootDirectoryInfo));
}
private TreeNode CreateDirectoryNode(DirectoryInfo directoryInfo)
{
var directoryNode = new TreeNode(directoryInfo.Name);
try
{
foreach (var directory in directoryInfo.GetDirectories())
{
//directoryNode.Nodes.Add(CreateDirectoryNode(directory));
TreeNode tn = CreateDirectoryNode(directory);
directoryNode.Nodes.Add(tn);
}
}
catch (UnauthorizedAccessException x)
{
}
return directoryNode;
}
发生这种情况的一个合乎逻辑的原因是系统驱动器上的大量文件夹。您应该"按需"加载项目,而不是一次加载所有项目。
应加载树中的所有主文件夹,然后挂钩 op TreeView.BeforeSelect
事件。在该事件中,您可以加载树的子项,可能以Task
加载以使其异步。
一种存储有关您正在处理的项目的其他信息的简单方法,即TreeNode
的 Tag
属性。例如,如果您已经加载了子项,则可以将其设置为要存储的自定义对象。
可能是因为C:
是操作系统驱动器,它将有很多文件夹。您直接在驱动器中的每个 sub 递归C:
调用此方法,根据我的经验,驱动器将有数千个目录。
一种可能的解决方案是显示在树节点的直接子目录上,然后仅在节点展开时加载子目录(按需加载)。或者显示进度条并使用BackgroundWorker
获取子目录,以便 UI 仍具有响应性。
为进一步的读者补充答案:
- 在树视图中加载给定路径的目录(所选节点的子文件夹)注意:加载文件系统观察器的相应实例。
.
C:' // <- C:' is the selected/expanded node
|---Documents and Settings
|---Empty Folder
|---Program Files
|---Program Files (x86)
|---Windows
.
- 对于其中每个子文件夹,请检查它是否包含子文件夹。如果是这种情况,请添加一个名为
"*"
的单个子节点,而不展开该父节点。(如您所知"*"
不允许用于实际目录名称,但对于 TreeView
)
此时将显示可单击的[+]
。
.
C:'
[+]-Documents and Settings
|--Empty Folder
[-]-Program Files
| |--[*] <- dummy Child Node (expanded here but collapsed in TreeView)
[+]-Program Files (x86)
[+]-Windows
.
- 捕获节点的
BeforeExpand
事件,如果第一个子节点称为"*"
,则删除该子节点,并加载该节点的子文件夹(同时为每个包含更多子文件夹的子文件夹添加"*"
)
.
C:'
[+]-Documents and Settings
|--Empty Folder
[-]-Program Files
| [+]-ATI
| [+]-Classic Shell
| [+]-Common Files
| |--Empty Folder
| [+]-Microsoft
| [+]-TOSHIBA
| [+]-Windows NT
[+]-Program Files (x86)
[+]-Windows
.
BeforeExpand确保在显示每个子文件夹之前加载它们。
注意:您的应用程序可能无法访问某些文件夹。请务必捕获此类异常。
使用另一个线程(或计时器)卸载已折叠很长时间的子节点以释放内存。
可以使用 BackgroundWorker 预加载树视图中可见文件夹的子文件夹(但不是其子文件夹) 不建议进行此移动,因为如果您干扰正在进行的工作,它可能会导致意外行为(仅当您正确处理了此类情况时才执行此操作)