使用WinForms TreeView进行递归目录列表?

时间:2010-02-14 22:06:51

标签: c# treeview filesystems populate

我想创建一个显示系统上所有文件夹的树视图,并且只显示音乐文件,例如.mp3 .aiff .wav等。

我记得我读过我需要使用递归函数或类似的东西。

2 个答案:

答案 0 :(得分:14)

通常大多数计算机都有数千个文件夹和数十万个文件,所以在TreeView中以递归方式显示所有这些文件并且速度非常慢并消耗大量内存,请在this question中查看我的答案,引用我的回答如果可以获得一个非常有用的GUI,可以进行一些修改:

// Handle the BeforeExpand event
private void treeView1_BeforeExpand(object sender, TreeViewCancelEventArgs e)
{
   if (e.Node.Tag != null) {
       AddDirectoriesAndMusicFiles(e.Node, (string)e.Node.Tag);
   }
}

private void AddDirectoriesAndMusicFiles(TreeNode node, string path)
{
    node.Nodes.Clear(); // clear dummy node if exists

    try {
        DirectoryInfo currentDir = new DirectoryInfo(path);
        DirectoryInfo[] subdirs = currentDir.GetDirectories();

        foreach (DirectoryInfo subdir in subdirs) {
            TreeNode child = new TreeNode(subdir.Name);
            child.Tag = subdir.FullName; // save full path in tag
            // TODO: Use some image for the node to show its a music file

            child.Nodes.Add(new TreeNode()); // add dummy node to allow expansion
            node.Nodes.Add(child);
        }

        List<FileInfo> files = new List<FileInfo>();
        files.AddRange(currentDir.GetFiles("*.mp3"));
        files.AddRange(currentDir.GetFiles("*.aiff"));
        files.AddRange(currentDir.GetFiles("*.wav")); // etc

        foreach (FileInfo file in files) {
            TreeNode child = new TreeNode(file.Name);
            // TODO: Use some image for the node to show its a music file

            child.Tag = file; // save full path for later use
            node.Nodes.Add(child);
        }

    } catch { // try to handle use each exception separately
    } finally {
        node.Tag = null; // clear tag
    }
}

private void MainForm_Load(object sender, EventArgs e)
{
    foreach (DriveInfo d in DriveInfo.GetDrives()) {
        TreeNode root = new TreeNode(d.Name);
        root.Tag = d.Name; // for later reference
        // TODO: Use Drive image for node

        root.Nodes.Add(new TreeNode()); // add dummy node to allow expansion
        treeView1.Nodes.Add(root);
    }
}

答案 1 :(得分:5)

递归搜索所有驱动器以查找特定文件的效果不佳。使用今天的大型驱动器需要大约一分钟的时间。

Windows资源管理器使用的一个标准技巧是仅列出顶级目录和文件。它将一个虚拟节点放在一个目录节点中。当用户打开节点(BeforeExpand事件)时,它仅搜索该目录,并将虚拟节点替换为找到该目录的目录和文件。再次在目录中放置一个虚拟节点。等等。

您可以通过添加空子目录来查看此功能。目录节点将显示+字形。当您打开它时,资源管理器发现没有要列出的目录或文件并删除虚拟节点。 +字形消失。

这非常快,列出单个目录的内容需要不到一秒钟。但是在您的情况下使用此方法存在问题。目录包含合适音乐文件的几率很小。通过发现在一组子目录中导航不会产生任何结果,用户将不断感到沮丧。

这就是为什么Windows有专门存储特定媒体文件的地方。在这种情况下我的音乐。使用Environment.GetFolderPath(Environment.SpecialFolder.MyMusic)来查找它。迭代它不应该花很长时间。