Рекурсивный список каталогов с помощью WinForms TreeView?

Я хочу сделать treeview, который показывает все папки в системе и только показывает музыкальные файлы, такие как .mp3 .aiff .wav и т.д.

Я не забываю читать, что я должен использовать рекурсивную функцию или что-то вдоль тех строк.

5
задан jww 5 December 2018 в 03:20
поделиться

2 ответа

Рекурсивный поиск определенных файлов на всех дисках не сработает. На сегодняшних больших дисках это займет около минуты.

Один из стандартных приемов, который использует проводник Windows, заключается в том, чтобы вывести список только каталогов и файлов верхнего уровня. Он помещает фиктивный узел в узел каталога. Когда пользователь открывает узел (событие BeforeExpand), он ищет только этот каталог и заменяет фиктивный узел каталогами и файлами, найденными в этом каталоге. Снова помещаем фиктивный узел в каталоги. И так далее.

Вы можете увидеть это в действии, добавив пустой подкаталог. Узел каталога будет показан с глифом +. Когда вы его открываете, проводник обнаруживает, что в списке нет каталога или файлов, и удаляет фиктивный узел. Символ + исчезнет.

Это очень быстро, перечисление содержимого одного каталога занимает меньше секунды. Однако есть проблема с использованием этого подхода в вашем случае. Шансы, что каталог содержит подходящий музыкальный файл, невелики. Пользователь будет постоянно разочаровываться, обнаруживая, что навигация по набору подкаталогов ничего не дает.

Вот почему в Windows есть специальное место для хранения определенных медиафайлов. Моя музыка в данном случае. Используйте Environment.GetFolderPath (Environment.SpecialFolder.MyMusic), чтобы найти его. Повторение не займет много времени.

5
ответ дан 18 December 2019 в 08:27
поделиться

Обычно большинство компьютеров имеют тысячи папок и сотни тысяч файлов, поэтому отображение всех их в рекурсивном 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);
    }
}
14
ответ дан 18 December 2019 в 08:27
поделиться
Другие вопросы по тегам:

Похожие вопросы: