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

如何在Blazor中使用TItem实现支持多选的泛型可复用表格组件

Blazor 泛型可复用表格添加多选功能实现方案

第一步:改造现有泛型表格组件

首先在组件顶部声明泛型参数,新增多选相关配置参数,补充多选逻辑:

@typeparam TItem
<table class="@ClassTable">
        <thead class="@ClassThead">
            <tr>
                @Cabecera
            </tr>
        </thead>
        <tbody>
            @foreach (var item in ItemList)
            {
                <tr class="@GetRowClass(item)" @onclick="@(() => HandleRowSelect(item))">@Filas(item)</tr>
            }
        </tbody>
        <tfoot>
            <tr>
                @Pie
            </tr>
        </tfoot>
</table>

@code{
  [Parameter] public string ClassTable { get; set; }
  [Parameter] public string ClassThead { get; set; }
  [Parameter] public RenderFragment Cabecera { get; set; }
  [Parameter] public RenderFragment Pie { get; set; }
  [Parameter] public RenderFragment<TItem> Filas { get; set; }
  [Parameter] public IEnumerable<TItem> Items { get; set; }      
  IEnumerable<TItem> ItemList { get; set; }

  // 多选相关新增参数
  [Parameter] public bool EnableMultiSelect { get; set; }
  [Parameter] public List<TItem> SelectedItems { get; set; } = new();
  [Parameter] public EventCallback<List<TItem>> SelectedItemsChanged { get; set; }
  [Parameter] public string SelectedRowClass { get; set; } = "selected";
  // 可选:自定义对象相等比较器,适配复杂业务对象的选中判断
  [Parameter] public IEqualityComparer<TItem> EqualityComparer { get; set; } = EqualityComparer<TItem>.Default;

  protected override void OnInitialized()
  {
      ItemList = Items;
  }

  private string GetRowClass(TItem item)
  {
      if (!EnableMultiSelect) return string.Empty;
      return SelectedItems.Contains(item, EqualityComparer) ? SelectedRowClass : string.Empty;
  }

  private async Task HandleRowSelect(TItem item)
  {
      if (!EnableMultiSelect) return;

      if (SelectedItems.Contains(item, EqualityComparer))
      {
          SelectedItems.Remove(item);
      }
      else
      {
          SelectedItems.Add(item);
      }
      // 触发双向绑定更新
      await SelectedItemsChanged.InvokeAsync(SelectedItems);
  }
}

第二步:业务页面调用示例

你原来的多选页面可以直接复用改造后的组件,不需要再单独写选中逻辑:

@page "/multiple"

<div class="table-responsive">
    <ReusableTable TItem="Value"
                   ClassTable="table table-sm table-bordered table-hover"
                   ClassThead="thead-dark"
                   Items="valueList"
                   EnableMultiSelect="true"
                   @bind-SelectedItems="MySelectedItems">
        <Cabecera>
            <th>Name</th>
            <th>Age</th>
        </Cabecera>
        <Filas Context="value">
            <td>@value.Name</td>
            <td>@value.Age</td>
        </Filas>
    </ReusableTable>
</div>

<button type="button" class="btn btn-sm btn-info" @onclick="showSelected">Click</button>

<hr />
@if (events != null)
{
    <ul>
        @foreach (var evt in events)
        {
            <li>@evt</li>
        }
    </ul>
}

@code
{
    private List<Value> valueList;
    private List<Value> MySelectedItems { get; set; } = new();
    private List<string> events = new List<string>();

    class Value
    {
        public string Name { get; set; }
        public string Age { get; set; }
    }

    protected override void OnInitialized()
    {
        valueList = new List<Value>
        {
            new Value() { Name = "James", Age = "38" },
            new Value() { Name = "John", Age = "32" }
        };
    }

    void showSelected()
    {
        events.Clear();
        foreach (var value in MySelectedItems)
        {
            events.Add($"'{value.Name}' selected. With value: '{value.Age}'");
        }
    }
}

额外优化点

  • 如果需要支持单选模式,只需要新增一个EnableSingleSelect参数,选中前清空SelectedItems列表即可
  • 可以在表头增加全选复选框,只需要新增一个全选触发方法,批量添加/移除所有Item到SelectedItems
  • 选中行的样式可以通过SelectedRowClass参数自定义,不需要修改组件内部代码

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.13 21:30:01