关于目录树的困惑

时间:2014-11-30 14:00:11

标签: c#

我正在尝试列出计算机中的所有文件。以下代码符合我的期望。我的计算机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;
}

3 个答案:

答案 0 :(得分:0)

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

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

答案 1 :(得分:0)

发生这种情况的一个合理原因是系统驱动器上存在大量文件夹。您应该加载“按需”项目,而不是一次性加载所有项目。

您应该在树中加载所有主文件夹,然后挂钩op TreeView.BeforeSelect事件。在该事件中,您可以加载树的子项,可能在Task中以使其异步。

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

答案 2 :(得分:0)

为更多读者提供补充答案:

  1. 在树视图中加载给定路径的目录(所选节点的子文件夹) 注意:加载FileSystem Watcher的相应实例。
  2. C:\  // <- C:\ is the selected/expanded node
     |---Documents and Settings
     |---Empty Folder
     |---Program Files
     |---Program Files (x86)
     |---Windows
    

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

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

      1. 捕获节点的BeforeExpand事件,如果第一个子节点被调用"*",则删除该子节点,并加载该节点的子文件夹(同时添加"*"每个包含更多子文件夹的子文件夹)
      2. 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预加载TreeView中可见文件夹的子文件夹(但不能预加载它们的子文件夹)此步骤不是,因为如果您干扰,它可能会导致意外行为正在进行的工作(只有在您正确处理此类案件时才这样做)