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

如何在Blazor .NET Core应用中基于MudBlazor实现通用泛型表格组件

基于MudBlazor实现泛型通用动态表格方案

实现思路

本次实现的通用组件同时支持强类型IEnumerable<T>和DataTable两类数据源,内置MudTable原生的分页、排序、搜索、行操作能力,可直接在业务页面复用无需重复编写表格结构代码。

第一步:定义公共列配置类

public class TableColumnConfig
{
    /// <summary>
    /// 数据源对应的属性名/列名
    /// </summary>
    public string FieldName { get; set; }
    /// <summary>
    /// 表格表头显示名称
    /// </summary>
    public string DisplayName { get; set; }
    /// <summary>
    /// 是否支持排序
    /// </summary>
    public bool Sortable { get; set; } = true;
    /// <summary>
    /// 列宽
    /// </summary>
    public string? Width { get; set; }
    /// <summary>
    /// 自定义渲染模板,为空则默认渲染字段值
    /// </summary>
    public RenderFragment<object>? CellTemplate { get; set; }
}

第二步:创建泛型通用表格组件 GenericMudTable.razor

@typeparam TItem
@using System.Data
@using System.Reflection

<MudTable Items="@FinalDataSource" 
          Hover="true" 
          Sortable="true"
          Pagination="true"
          RowsPerPage="10"
          RowClick="OnRowClick.InvokeAsync"
          Class="mt-4">
    <HeaderContent>
        @foreach (var col in ColumnConfigs)
        {
            <MudTh SortLabel="@col.FieldName" Width="@col.Width">@col.DisplayName</MudTh>
        }
    </HeaderContent>
    <RowTemplate>
        @{
            var rowData = context;
            foreach (var col in ColumnConfigs)
            {
                <MudTd>
                    @if (col.CellTemplate != null)
                    {
                        @col.CellTemplate(rowData)
                    }
                    else
                    {
                        @GetCellValue(rowData, col.FieldName)
                    }
                </MudTd>
            }
        }
    </RowTemplate>
</MudTable>

@code {
    /// <summary>
    /// 强类型列表数据源
    /// </summary>
    [Parameter]
    public IEnumerable<TItem>? DataSource { get; set; }

    /// <summary>
    /// DataTable格式数据源
    /// </summary>
    [Parameter]
    public DataTable? DataTableSource { get; set; }

    /// <summary>
    /// 列配置
    /// </summary>
    [Parameter, Required]
    public List<TableColumnConfig> ColumnConfigs { get; set; } = new();

    /// <summary>
    /// 行点击回调
    /// </summary>
    [Parameter]
    public EventCallback<TItem> OnRowClick { get; set; }

    private IEnumerable<object>? FinalDataSource { get; set; }
    private Dictionary<Type, PropertyInfo[]> _propertyCache = new();

    protected override void OnParametersSet()
    {
        base.OnParametersSet();
        // 合并处理两类数据源
        if (DataSource != null)
        {
            FinalDataSource = DataSource.Cast<object>();
        }
        else if (DataTableSource != null)
        {
            FinalDataSource = DataTableSource.AsEnumerable();
        }
    }

    private object? GetCellValue(object rowData, string fieldName)
    {
        if (rowData is DataRow dataRow)
        {
            return dataRow[fieldName] == DBNull.Value ? null : dataRow[fieldName];
        }
        // 反射缓存优化性能
        var type = rowData.GetType();
        if (!_propertyCache.TryGetValue(type, out var props))
        {
            props = type.GetProperties(BindingFlags.Public | BindingFlags.Instance);
            _propertyCache[type] = props;
        }
        var prop = props.FirstOrDefault(p => p.Name == fieldName);
        return prop?.GetValue(rowData);
    }
}

第三步:组件使用示例

场景1:绑定强类型List

// 定义业务实体类
public class User
{
    public int Id { get; set; }
    public string UserName { get; set; }
    public DateTime CreateTime { get; set; }
    public bool IsActive { get; set; }
}

页面调用代码:

@page "/userlist"

<GenericMudTable TItem="User" 
                 DataSource="@UserList" 
                 ColumnConfigs="@UserColumns"
                 OnRowClick="HandleUserClick">
</GenericMudTable>

@code {
    private List<User> UserList { get; set; } = new();
    private List<TableColumnConfig> UserColumns { get; set; } = new();

    protected override void OnInitialized()
    {
        // 初始化列配置
        UserColumns = new List<TableColumnConfig>
        {
            new TableColumnConfig { FieldName = "Id", DisplayName = "用户ID", Width = "80px" },
            new TableColumnConfig { FieldName = "UserName", DisplayName = "用户名" },
            new TableColumnConfig { FieldName = "CreateTime", DisplayName = "创建时间" },
            // 自定义列模板示例
            new TableColumnConfig 
            { 
                FieldName = "IsActive", 
                DisplayName = "状态",
                CellTemplate = (row) =>@<MudChip Color="@((bool)((User)row).IsActive ? Color.Success : Color.Default)">@(((User)row).IsActive ? "启用" : "禁用")</MudChip>
            }
        };
        // 模拟加载数据
        UserList = Enumerable.Range(1, 20).Select(i => new User
        {
            Id = i,
            UserName = $"用户{i}",
            CreateTime = DateTime.Now.AddDays(-i),
            IsActive = i % 2 == 0
        }).ToList();
    }

    private void HandleUserClick(User user)
    {
        // 行点击逻辑,比如跳转到详情页
        Console.WriteLine($"点击了用户:{user.UserName}");
    }
}

场景2:绑定DataTable数据源

@page "/datatable-demo"

<GenericMudTable TItem="DataRow" 
                 DataTableSource="@DemoDataTable" 
                 ColumnConfigs="@DataTableColumns">
</GenericMudTable>

@code {
    private DataTable DemoDataTable { get; set; } = new();
    private List<TableColumnConfig> DataTableColumns { get; set; } = new();

    protected override void OnInitialized()
    {
        // 构造测试DataTable
        DemoDataTable.Columns.Add("订单号", typeof(string));
        DemoDataTable.Columns.Add("商品名称", typeof(string));
        DemoDataTable.Columns.Add("金额", typeof(decimal));
        for (int i = 1; i <= 15; i++)
        {
            var row = DemoDataTable.NewRow();
            row["订单号"] = $"OD{i.ToString().PadLeft(6, '0')}";
            row["商品名称"] = $"商品{i}";
            row["金额"] = i * 100.5m;
            DemoDataTable.Rows.Add(row);
        }
        // 列配置和DataTable列名对应即可
        DataTableColumns = new List<TableColumnConfig>
        {
            new TableColumnConfig { FieldName = "订单号", DisplayName = "订单编号" },
            new TableColumnConfig { FieldName = "商品名称", DisplayName = "商品" },
            new TableColumnConfig { FieldName = "金额", DisplayName = "订单金额" }
        };
    }
}

扩展优化建议

  • 可以新增参数控制是否显示搜索框、是否可多选、行高、斑马纹等MudTable原生属性,直接透传即可
  • 反射部分可替换为表达式树编译的属性访问器,进一步提升大数据量下的渲染性能
  • 可新增全局默认配置,比如默认每页行数、默认排序字段等

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 21:15:02