Home > Software engineering >  Working with several Generic parameters and multiple parent/child components in Blazor
Working with several Generic parameters and multiple parent/child components in Blazor

Time:05-28

I am brand new to Blazor and component-based frameworks and still very much a novice in C#. I am trying to make a table (which is a component called "Grid") that has multiple child components within it. Each column is its own component with header and footer components wrapped around it, which will later serve to help me sort, filter & sum each column, similar to Excel. For now I added some mock data in my Product class that is being stores in the _products List and I'm struggling to populate this table with the correct column names and row data. I was able to get the rows working with the correct data inside <Columns> I keep getting this error: The type arguments for method cannot be inferred from the usage but the other examples on Stack Overflow for this error are too complex for me to follow along. Any advice would be amazing.

This is what's on my index.razor page:

<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>

Here's all the parameters on this page

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

This is my Grid component called Grid.razor:

@typeparam T

<div >
    
        <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>

And these are the parameters on my Grid component where the generics are being used:

[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; }

I think the issue is with the Headers RenderFragment because it was working before I added this code, but now even when I comment that out it's not working so I'm confused

CodePudding user response:

The error is because you need to specified the param type to the component

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

But I see a lot of errors in your code here I did a similar working example ...

<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" };

}

and the grid ...

@typeparam T
@typeparam H

<div >
    <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; }

}
  • Related