5

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

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

4

2 回答 2

14

通常大多数计算机都有数千个文件夹和数十万个文件,因此以递归方式在 TreeView 中显示所有这些文件夹非常慢并且消耗大量内存,请查看我在这个问题中的答案,并在可以得到时引用我的答案并进行一些修改一个非常有用的 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);
    }
}
于 2010-02-15T07:07:03.087 回答
5

递归搜索所有驱动器以查找特定文件不会很好地工作。使用今天的大型驱动器大约需要一分钟。

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

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

这非常快,列出单个目录的内容不到一秒钟。但是在您的情况下使用这种方法存在问题。目录包含合适的音乐文件的可能性很小。用户会经常因为发现在一组子目录中导航没有产生任何结果而感到沮丧。

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

于 2010-02-14T22:41:37.357 回答