You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Blazor InputCheckBox绑定Dictionary<string, bool>遇只读问题求助

问题原因

你遇到的核心问题是:Dictionary<TKey,TValue>枚举返回的KeyValuePair<TKey,TValue>是值类型(结构体),它的Value属性仅包含get访问器,是只读的。而Blazor的@bind-Value双向绑定要求绑定目标必须是可读写的属性,因此直接绑定item.Value会出现只读限制。

解决方案

下面提供两种可行的修复方案:

方案1:直接通过字典索引器绑定

利用字典的索引器(headers.Headers[item.Key])是可读写的特性,替换原来的item.Value绑定目标:

修改Razor页面的循环代码:

@foreach (var item in headers.Headers)
{
    <tr class="row ">
        @if (item.Key is not null)
        {
            <td scope="col" class="col border border-1 border-secondary">
                <InputCheckbox class="btn-check" @bind-Value="headers.Headers[item.Key]">
                    @item.Key
                </InputCheckbox>
            </td>
        }
    </tr>
}

同时需要修复CsvContent构造函数中Headers未初始化的问题,否则会触发空引用异常:

public CsvContent()
{
    Headers = new Dictionary<string, bool>(); // 初始化字典
    if (FileContent is not null)
    {
        foreach (var item in FileContent)
        {
            if(item?.ElementAt(0) is not null)
                Headers.TryAdd(item.ElementAt(0), false);
        }
    }
}

方案2:改用自定义类集合(推荐)

创建一个包含可读写属性的自定义类,替代KeyValuePair,更符合Blazor的数据绑定设计习惯:

1. 定义自定义类

public class HeaderSelection
{
    public string Name { get; set; }
    public bool IsSelected { get; set; }

    public HeaderSelection(string name)
    {
        Name = name;
        IsSelected = false;
    }
}

2. 修改CsvContent模型

将Headers属性从Dictionary<string, bool>?改为List<HeaderSelection>?,并初始化:

public class CsvContent
{
    static Dictionary<int, char> divider = new() { { 0, ',' }, { 1, ';' }, { 2, '\t' } };
    public static List<List<string>?> FileContent { get; set; }
    public List<HeaderSelection>? Headers { get; set; }

    public static async Task ReadCsvAsync(string path, int dividerCode = 2)
    {
        FileContent = new List<List<string>?>();
        Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
        using (StreamReader reader = new StreamReader(path, System.Text.Encoding.GetEncoding(1251)))
        {
            string? line;
            while ((line = await reader.ReadLineAsync()) != null)
            {
                List<string> cells = new();
                cells.AddRange(line.Split(divider[dividerCode]));
                FileContent.Add(cells);
            }
        }
    }

    public CsvContent()
    {
        Headers = new List<HeaderSelection>(); // 初始化集合
        if (FileContent is not null)
        {
            foreach (var item in FileContent)
            {
                if(item?.ElementAt(0) is string headerName)
                    Headers.Add(new HeaderSelection(headerName));
            }
        }
    }
}

3. 更新Razor页面的绑定代码

@foreach (var header in headers.Headers)
{
    <tr class="row ">
        <td scope="col" class="col border border-1 border-secondary">
            <InputCheckbox class="btn-check" @bind-Value="header.IsSelected">
                @header.Name
            </InputCheckbox>
        </td>
    </tr>
}
额外注意事项
  • 原代码中CsvContent构造函数未初始化Headers,会导致空引用异常,上述两种方案均已修复此问题。
  • 方案2的自定义类方式更易于扩展(比如后续需要添加更多属性),也更符合Blazor组件的绑定逻辑,推荐使用。

内容的提问来源于stack exchange,提问作者Zufar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 15:42:03