Рекурсивный список файлов / папок зацикливается

Как мне в рекурсивные циклы? Прежде всего, я хочу вычеркнуть списки папок и файлов, конечно, эти файлы должны быть в соответствующих папках, и я собираюсь отобразить список в Интернете с помощью HTML и CSS. у меня есть List<DirectoryInfo> и List<FileInfo> для хранения моих папок и файлов.

Я могу сделать базовый цикл foreach в моем представлении следующим образом:

@foreach (DirectoryInfo folder in ViewBag.folders)
    {
        <p>@folder.Name</p>
        foreach (FileInfo file in ViewBag.files)
        {
            if (folder.FullName == file.DirectoryName)
            { 
                <p class="file" data-url="@file.FullName.Substring(file.DirectoryName.IndexOf("Content"))" style="margin-left:20px;">@file.Name</p>
            }
        }
    }

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

Я могу сделать что-то подобное

<ol class="tree">
    @{
        int i = 1;
        int subFolderi = 1;
    foreach (DirectoryInfo folder in ViewBag.folders)
    {
        <li>
        <label for="folder-@i">@folder.Name</label> <input type="checkbox" id="folder-@i" /> 
        <ol>
        @foreach (DirectoryInfo subFolder in ViewBag.folders)
        {
            if (folder.Name == subFolder.Parent.ToString())
            {
                <li>
                <label for="subfolder-@subFolderi">@subFolder.Name</label> <input type="checkbox" id="subfolder-@subFolderi" /> 
                <ol>
                @foreach (FileInfo file in ViewBag.files)
                {
                    if (subFolder.FullName == file.DirectoryName)
                    { 
                        <li class="file" data-url="@file.FullName.Substring(file.DirectoryName.IndexOf("Content"))">@file.Name</li>
                    }
                }
                </ol>
                </li>
            }
            subFolderi++;
        }
        @foreach (FileInfo file in ViewBag.files)
        {

            if (folder.FullName == file.DirectoryName)
            { 
                <li class="file" data-url="@file.FullName.Substring(file.DirectoryName.IndexOf("Content"))">@file.Name</li>
            }
        }
        </ol>
        </li>
        i++;
    }
    }
    </ol>

И это помещает подпапки в их родительские папки, однако это, очевидно, работает только для первого уровня подпапок, а не подпапок внутри подпапок. И он также отображает эти подпапки дважды, один раз в их родительской папке и один в списке основных папок.

Тогда возникает вопрос: должен ли я сделать рекурсивный цикл, чтобы получать подпапки и их файлы внутри подпапок, или мне нужно сделать какой-нибудь LINQ, чтобы объединить все заранее, чтобы сделать цикл проще? Или есть лучший способ сделать это? Я предпочитаю чистый способ, когда у меня все еще есть контроль над HTML/CSS, поэтому нет плагинов jQuery или элементов управления ASP, которые используют источник данных, а затем создают все автоматически.

Рабочий раствор

<ol class="tree">
    @printFolder(ViewBag.contentFolder)
    </ol>

    @helper printFolder(DirectoryInfo folder)
    {
        <li>
            <label for="folder-@folder.Name">@folder.Name</label> <input type="checkbox" id="folder-@folder.Name" />
            <ol>
                    @foreach(DirectoryInfo subFolder in folder.GetDirectories())
                    {
                        @printFolder(subFolder)
                    }
                    @foreach(FileInfo file in folder.GetFiles())
                    {
                        @printFile(file)
                    }
            </ol>
        </li>
    }
    @helper printFile(FileInfo file)
    {
        <li class="file" data-url="@file.FullName.Substring(file.DirectoryName.IndexOf("Content"))">@file.Name</li>
    }

2 ответа

Решение

Разве вы не можете использовать GetFiles() и GetDirectories() из DirectoryInfo для печати всего дерева файлов? Что-то вроде:

foreach (var folder in folders)
  PrintFolder(folder);

PrintFolder(DirectoryInfo folder)
{
  // ... print folder name here ...

  foreach(var subFolder in folder)
     PrintFolder(folder);

  foreach(var file in folder.GetFiles())
     PrintFile(file);

}

PrintFile(FileInfo file)
{
  // ... print file name here ... 
}

Я бы использовал DisplayTemplate для папки. Это позволит отобразить все папки внутри него, используя себя в качестве шаблона, тем самым выполняя рекурсию.

Другие вопросы по тегам