【问题标题】:How to make a class that holds two type of files, so they are linked to each other?如何制作一个包含两种类型文件的类,以便它们相互链接?
【发布时间】:2022-12-13 20:16:45
【问题描述】:

我正在尝试制作一个表格,列出链接在一起的 2 种类型的文件。一种是 .mp3,另一种是 .txt 文件。我希望将这些文件链接在一起,以便当 foreach 循环通过它们时,共享相同名称的文件共享一行。这样就可以播放 mp3 文件,并可以打开相应的文本文件。

应用程序剃刀页面有一个显示文件夹中所有文件的表格,但它不考虑这两种类型的文件是否共享相同的名称。任何人都可以帮助创建一个将文件链接在一起的类,以便可以在表中调用它们吗?

这是代码。

<table class="table table-striped mb-0">
    <thead>
    <tr>
        <th scope="col">Name</th>
        <th scope="col">Actions</th>
    </tr>
    </thead>
    <tbody>
        @foreach (var file in textList)
        {
            <tr>
                <td>
                    @file.Name
                </td>
                <td>
                    <span @onclick="() => PlayAudio(file.Url)"
                          class="text-primary oi oi-play-circle me-2" aria-hidden="true" role="button">
                    </span>
                    <span @onclick="() => DeleteAudio(file)"
                          class="text-danger oi oi-trash" aria-hidden="true" role="button">
                    </span>
                    <span @onclick="() => openTextFile(file)"
                          ><button>Open</button>
                    </span>
                </td>
            </tr>
        }
    }
    </tbody>
</table>
@code{
    readonly List<TextFile> textList = new();
    readonly string FolderName = "textSoundFiles";

    protected override void OnInitialized()
    {
        var path = $"{env.WebRootPath}\\{FolderName}\\";
        var files = new DirectoryInfo(path).GetFiles();

        foreach (var file in files)
        {
            textList.Add(new TextFile
            {
                Name = file.Name,
                Url = $"/textFiles/{file.Name}",
                Path = file.FullName
            });
        }
    }

    public class TextFile
    {
        public string Name { get; set; }
        public string Url { get; set; }
        public string Path { get; set; }
    }
}

我正在尝试制作一个列出文件的表格,它允许我播放列出的音频文件中的音频。我试着 目录中的 2 种文件类型,使得具有相同名称(不包括其 MIME 类型)的文件相互链接

【问题讨论】:

  • 迭代files.GroupBy(file =&gt; file.Name)
  • @BrianParker 这将如何使文件链接在一起?
  • 它们将按名称分组,您将迭代一个组。这些组本身将有一个子列表,在您的情况下,一个或两个项目。如果您的名称包含扩展名 .txt.mp3,您可能必须编写一个派生属性来删除它并按其分组。
  • @BrianParker 我遇到了System.IO.Path.ChangeExtension(path, null); 这将允许我在保持路径的同时切断扩展,但它没有用。你能检查我帖子中的编辑,看看我做错了什么吗?

标签: .net blazor blazor-server-side


【解决方案1】:

使用LinqGroupBy

@foreach(var fileGroup in myFilesGroupedAndSorted)
{
    <h3>@fileGroup.Key</h3>
    @foreach(var file in fileGroup.OrderBy( file => file.Path))
    {
        <div>@file.Path</div>
    }
}

@code {
    // without access to your folder I generated random data.
    List<TextFile> myList = new List<TextFile>
    {
        new TextFile { Name = "", Path = "some-path\SomeFile1.txt", Url = "" },
        new TextFile { Name = "", Path = "some-path\SomeFile2.txt", Url = "" },
        new TextFile { Name = "", Path = "some-path\SomeFile3.txt", Url = "" },
        new TextFile { Name = "", Path = "some-path\SomeFile4.txt", Url = "" },
        new TextFile { Name = "", Path = "some-path\SomeFile5.txt", Url = "" },
        new TextFile { Name = "", Path = "some-path\SomeFile6.txt", Url = "" },
        new TextFile { Name = "", Path = "some-path\SomeFile1.mp3", Url = "" },
        new TextFile { Name = "", Path = "some-path\SomeFile2.mp3", Url = "" },
        new TextFile { Name = "", Path = "some-path\SomeFile3.mp3", Url = "" },
        new TextFile { Name = "", Path = "some-path\SomeFile4.mp3", Url = "" },
        new TextFile { Name = "", Path = "some-path\SomeFile5.mp3", Url = "" },
        new TextFile { Name = "", Path = "some-path\SomeFile6.mp3", Url = "" },
    };


    IEnumerable<IGrouping<string, TextFile>> myFilesGroupedAndSorted
        => myList.GroupBy(file => GetPathWithoutExtension(file.Path))
                 .OrderBy(group => group.Key);

    private string GetPathWithoutExtension(string path)
    {
        return System.IO.Path.ChangeExtension(path, null);
    }
}

然后通过测试每个文件扩展名来处理每个组应该是微不足道的。我会做一个子组件来传递 IGrouping&lt;string, TextFile&gt; 作为参数来简化逻辑......

Mp3.Razor

<tr>
    <td>
        @FileGroup.Key
    </td>
    <td>
        @if (Mp3 is not null)
        {
            <span @onclick="() => PlayAudio(Mp3.Url)"
              class="text-primary oi oi-play-circle me-2" aria-hidden="true" role="button">
            </span>
            <span @onclick="() => DeleteAudio(FileGroup.Key)"
              class="text-danger oi oi-trash" aria-hidden="true" role="button">
            </span>
        }
        @if (Text is not null)
        {
            <span @onclick="() => openTextFile(Text)">
                <button>Open</button>
            </span>
        }
    </td>
</tr>
@code {
    [Parameter]
    public IGrouping<string, TextFile> FileGroup { get; set; } = default!;

    TextFile? Text => FileGroup.FirstOrDefault(file => Path.GetExtension(file.Path).ToLower() == "txt");
    TextFile? Mp3 => FileGroup.FirstOrDefault(file => Path.GetExtension(file.Path).ToLower() == "mp3");
}
...
  <tbody>
    @foreach(var fileGroup in myFilesGroupedAndSorted)
    {
       <Mp3 FileGroup=fileGroup /> 
    }
  </tbody>
...

【讨论】:

  • 我尝试了一些事情,但从未出现过清单。我可以请您检查对原始帖子中代码的编辑,看看有什么问题吗?
  • @Addlon 首先是按预期填充列表吗?你能放置一个断点并检查它的内容吗?
  • 我在Text =&gt; FileGroup...Mp3 =&gt;... 中得到异常System.ArgumentNullException: 'Value cannot be null. (Parameter 'source')'
  • 很抱歉打扰你,但表格现在列出了 @fileGroup.Key,但仅当 TextFile? Text =&gt; fileGroup...TextFile? Mp3 =&gt; fileGroup... 被删除时,以及提及它们的 2 个 if 语句。当他们在那里时,他们会得到异常ArgumentNullException。你知道为什么会这样吗?
【解决方案2】:

您需要“旋转”表格,即将列表转换为表格。 LINQ 可用于此。查看this answer。您将拥有属性 bool HasMp3bool HasTxt,而不是“Jan”和“Feb”,以及适当的 Where 子句。是这样的:

var files = new DirectoryInfo(path).GetFiles();

textList.AddRange(files
    .GroupBy(c => Path.ChangeExtension(c.Name, null))
    .Select(g => new TextFile() {
        Name = g.Key,
        Url = $"/textFiles/{g.Key}",
        HasMp3 = g.Any(c => Path.GetExtension(c) == ".mp3"),
        HasTxt = g.Any(c => Path.GetExtension(c) == ".txt"),
    }));

使用这两个 bool 属性,如果相应的文件不存在,您可以隐藏按钮。 Url 属性没有扩展名。您必须在每个适当的函数中附加每个适当的扩展名。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-02-09
    • 2023-02-15
    • 1970-01-01
    • 1970-01-01
    • 2019-10-29
    • 1970-01-01
    • 2019-01-29
    • 1970-01-01
    相关资源
    最近更新 更多