Blazor 不会在类更改时重新渲染

时间:2021-04-07 03:23:52

标签: c# blazor-webassembly

<div>
<div>
    <div class="@(Base64Images.Count == 0 ? "block" : "hidden")">
        <label for="file-upload">
            <span>Upload a file</span>

            <InputFile OnChange="HandleChange" id="file-upload" name="file-upload" class="sr-only" />
        </label>
    </div>
    <div class="@(Base64Images.Count > 0 ? "block" : "hidden")">
        @foreach(var image in Base64Images)
        {
            <img src="@image" />
        }
    </div>
</div>
</div>

@code {
public IReadOnlyList<IBrowserFile> BrowserFiles { get; protected set; } = new List<IBrowserFile>();

private List<string> Base64Images { get; set; } = new List<string>();

private async Task<bool> HandleChange(InputFileChangeEventArgs e)
{
    IReadOnlyList<IBrowserFile> fileList;

    BrowserFiles = new List<IBrowserFile> { e.File };

    await BrowserFilesToBase64Images();

    return true;
}

private async Task<bool> BrowserFilesToBase64Images()
{
    foreach(var image in BrowserFiles)
    {
        if(image != null)
        {
            var format = "image/png";
            var buffer = new byte[image.Size];
            await image.OpenReadStream().ReadAsync(buffer);
            Base64Images.Add($"data:{format};base64,{Convert.ToBase64String(buffer)}");
        }
    }

    return true;
}

}

所以我有这个代码,它很简单。我想显示用户上传内容的预览,但预览必须仅在选择文件后显示。同样,我想在加载图像时隐藏输入(但不将其从 DOM 中删除)。但无论我做什么,Blazor 都不会重新渲染。

Base64Images.Count

更改,我已经能够调试它。条件应该被命中,但 HTML 不会改变。有没有办法告诉 Blazor 重新渲染?

我知道 StateHasChanged(),但不仅应该在每个事件之后调用它,而且即使多次调用它也不会强制重新渲染。

2 个答案:

答案 0 :(得分:0)

你必须解释你想要发生的事情。您有 Lists,但是当您处理 FileInputOnChange 时,您只会得到一个文件(也许)。

如果你想要多个文件,那么你必须像这样设置你的 FileInput:

<InputFile OnChange="HandleChange" id="file-upload" name="file-upload" class="sr-only" multiple />

为了获取 IBrowserFile 对象的集合,这个:

BrowserFiles = e.GetMultipleFiles(maxAllowedFiles);

答案 1 :(得分:0)

这是我根据您提供的内容编写的测试代码。它有效,所以我们遗漏了一些明显的东西。

@page "/Images"

<div class="@(Base64Images.Count > 0 ? "block" : "hidden")">
    @foreach (var image in Base64Images)
    {
        <h4>Images goes here</h4>
        <img src="@image" />
    }

</div>

@if (!_hasImages)
{
<div>
    <InputFile OnChange="@OnInputFileChange" multiple />
</div>
}
else
{
    <div>
        @foreach (var image in Base64Images)
        {
            <h4>More Images goes here</h4>
            <img src="@image" />
        }
    </div>
}


<button class="btn btn-dark" @onclick="() => Click()"> Click</button>
@code {

    List<string> Base64Images = new List<string>();

    private bool _hasImages => Base64Images != null && Base64Images.Count > 0;

    void Click()
    {
        Base64Images.Add("Bye");
    }

    private async Task OnInputFileChange(InputFileChangeEventArgs e)
    {
        await Task.Delay(1000);
        Base64Images.Add("Bye");
    }
}