Рекурсивный список каталогов с использованием WinForms TreeView? - PullRequest
5 голосов
/ 15 февраля 2010

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

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

Ответы [ 2 ]

14 голосов
/ 15 февраля 2010

Обычно большинство компьютеров имеют тысячи папок и сотни тысяч файлов, поэтому рекурсивное отображение всех их в TreeView с очень медленной работой и большим объемом памяти, см. Мой ответ в этот вопрос , цитируя мой ответ с некоторыми изменениями, когда можно получить довольно удобный графический интерфейс:

// 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);
    }
}
5 голосов
/ 15 февраля 2010

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

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

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

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

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

...