Я хочу сделать treeview, который показывает все папки в системе и только показывает музыкальные файлы, такие как .mp3 .aiff .wav и т.д.
Я не забываю читать, что я должен использовать рекурсивную функцию или что-то вдоль тех строк.
Рекурсивный поиск определенных файлов на всех дисках не сработает. На сегодняшних больших дисках это займет около минуты.
Один из стандартных приемов, который использует проводник Windows, заключается в том, чтобы вывести список только каталогов и файлов верхнего уровня. Он помещает фиктивный узел в узел каталога. Когда пользователь открывает узел (событие BeforeExpand), он ищет только этот каталог и заменяет фиктивный узел каталогами и файлами, найденными в этом каталоге. Снова помещаем фиктивный узел в каталоги. И так далее.
Вы можете увидеть это в действии, добавив пустой подкаталог. Узел каталога будет показан с глифом +. Когда вы его открываете, проводник обнаруживает, что в списке нет каталога или файлов, и удаляет фиктивный узел. Символ + исчезнет.
Это очень быстро, перечисление содержимого одного каталога занимает меньше секунды. Однако есть проблема с использованием этого подхода в вашем случае. Шансы, что каталог содержит подходящий музыкальный файл, невелики. Пользователь будет постоянно разочаровываться, обнаруживая, что навигация по набору подкаталогов ничего не дает.
Вот почему в Windows есть специальное место для хранения определенных медиафайлов. Моя музыка в данном случае. Используйте Environment.GetFolderPath (Environment.SpecialFolder.MyMusic), чтобы найти его. Повторение не займет много времени.
Обычно большинство компьютеров имеют тысячи папок и сотни тысяч файлов, поэтому отображение всех их в рекурсивном 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);
}
}