关于目录树的困惑

本文关键字:目录树 | 更新日期: 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加载以使其异步。

一种存储有关您正在处理的项目的其他信息的简单方法,即TreeNodeTag 属性。例如,如果您已经加载了子项,则可以将其设置为要存储的自定义对象。

可能是因为C:是操作系统驱动器,它将有很多文件夹。您直接在驱动器中的每个 sub 递归C:调用此方法,根据我的经验,驱动器将有数千个目录。

一种可能的解决方案是显示在树节点的直接子目录上,然后仅在节点展开时加载子目录(按需加载)。或者显示进度条并使用BackgroundWorker获取子目录,以便 UI 仍具有响应性。

为进一步的读者补充答案:

  1. 在树视图中加载给定路径的目录(所选节点的子文件夹)注意:加载文件系统观察器的相应实例。

.

C:'  // <- C:' is the selected/expanded node
 |---Documents and Settings
 |---Empty Folder
 |---Program Files
 |---Program Files (x86)
 |---Windows

.

  1. 对于其中每个子文件夹,请检查它是否包含子文件夹。如果是这种情况,请添加一个名为 "*" 的单个子节点,而不展开该父节点。(如您所知"*"不允许用于实际目录名称,但对于 TreeView

此时将显示可单击的[+]

.

C:'
[+]-Documents and Settings
 |--Empty Folder
[-]-Program Files
 |   |--[*]  <- dummy Child Node (expanded here but collapsed in TreeView)
[+]-Program Files (x86)
[+]-Windows

.

  1. 捕获节点的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 预加载树视图中可见文件夹的子文件夹(但不是其子文件夹) 建议进行此移动,因为如果您干扰正在进行的工作,它可能会导致意外行为(仅当您正确处理了此类情况时才执行此操作)