在 Blazor 中使用多个通用参数和多个 parent/child 组件

Working with several Generic parameters and multiple parent/child components in Blazor

我是 Blazor 和基于组件的框架的新手,而且在 C# 方面仍然是一个新手。我正在尝试制作一个 table (这是一个名为“Grid”的组件),其中包含多个子组件。每一列都是它自己的组件,其周围环绕着页眉和页脚组件,稍后将用于帮助我对每一列进行排序、筛选和求和,类似于 Excel。现在我在我的产品 class 中添加了一些模拟数据,这些数据存储在 _products 列表中,我正在努力用正确的列名和行数据填充此 table。我能够让行在 <Columns> 中使用正确的数据,但我不断收到此错误:The type arguments for method cannot be inferred from the usage 但是 Stack Overflow 上针对此错误的其他示例太复杂了,我无法跟进。任何建议都会很棒。

这是我的 index.razor 页面上的内容:

<Grid Data="_products" Label="_columnNames" Options="@gridOptions" GetStyle="@(x => x.Name.EndsWith("1") ? "color: red" : null)">
<Headers>
    @foreach (var i in _columnNames)
    {
        <GridHeader Label="_columnNames[i]" />
    }        
</Headers>
<Columns>
    <GridColumn Value="@context.Id" />
    <GridColumn Value="@context.Name" />
    <GridColumn Value="@context.Weight" />
    <GridColumn Value="@context.Length" />
    <hr />
</Columns>

这是本页的所有参数

GridOptions gridOptions = new() { IsSelectionEnabled = true };
List<Product> _products = Product.InsertProductData().ToList();
List<string> _columnNames = new List<string>{ "ID", "Name", "Weight", "Length" };

这是我的网格组件 Grid.razor:

@typeparam T

<div class="mb-3">
    
        <table class="table">
            <thead>
            @if (Label != null)
            {
                @foreach (var item in Label)
                {
                    <tr>
                        @Headers
                    </tr>
                }
            }
            </thead>
            <tbody>
            @if (Data != null)
            {
                @foreach (var model in Data)
                {
                    <tr style="@GetStyle(model)">
                        <th scope="row">
                            @Columns(model)
                        </th>
                    </tr>
                }
            }
            </tbody>
        </table>
</div>

这些是我的网格组件上使用泛型的参数:

[Parameter] public ICollection<T> Data { get; set; }

[Parameter] public ICollection<T> Label { get; set; }

[Parameter] public GridOptions Options { get; set; }

[Parameter] public RenderFragment Footer { get; set; }

[Parameter] public RenderFragment<T> Columns { get; set; }

[Parameter] public RenderFragment Headers { get; set; }

[Parameter] public Func<T, string> GetStyle { get; set; }

我认为问题出在 Headers RenderFragment 上,因为在我添加这段代码之前它可以正常工作,但现在即使我注释掉它也无法正常工作所以我很困惑

该错误是因为您需要为组件指定参数类型

<Grid Data="_products" T="Product" ...

但是我在这里的代码中看到了很多错误我做了一个类似的工作示例...

<Grid Data="_products" T="Product" Label="_columnNames" H="string" GetStyle="@(x => x.Name.EndsWith("1") ? "color: red" : null)">
    <Headers>
        <div>@context</div>
    </Headers>
    <Columns>
        <td>@context.Id</td>
        <td>@context.Name</td>
        <td>@context.Weight</td>
        <td>@context.Length</td>
        <hr />
    </Columns>
</Grid>

@code
{
    record Product(int Id, string Name, int Weight, int Length);
    List<Product> _products = new()
    {
        new Product(1, "San", 80, 177),
        new Product(2, "Luli", 64, 168)
    };
    List<string> _columnNames = new List<string>{ "ID", "Name", "Weight", "Length" };

}

和网格...

@typeparam T
@typeparam H

<div class="mb-3">
    <table class="table">
        <thead>
        @if (Label != null)
        {
            <tr>
            @foreach (var item in Label)
            {
                <th>
                    @Headers(item)
                </th>
            }
            </tr>
        }
        </thead>
        <tbody>
        @if (Data != null)
        {
            @foreach (var model in Data)
            {
                <tr style="@GetStyle(model)">
                        @Columns(model)
                </tr>
            }
        }
        </tbody>
    </table>
</div>

@code
{
    [Parameter] public ICollection<T> Data { get; set; }

    [Parameter] public ICollection<H> Label { get; set; }

    [Parameter] public RenderFragment Footer { get; set; }

    [Parameter] public RenderFragment<T> Columns { get; set; }

    [Parameter] public RenderFragment<H> Headers { get; set; }

    [Parameter] public Func<T, string> GetStyle { get; set; }

}