How to specify the type of TItem in Virtualize Component in Blazor WebAssembly inside a Generic Table Template

Viewed 2086

I'm building a Generic Table Template in my blazor webassembly project. Following the docs, I setup my table template and I'm trying to enable virtualization in my table template as follows.

TableTemplate.razor:

@typeparam TItem

<table class="@CssClass">
    <thead>
        <tr>@TableHeader</tr>
    </thead>
    <tbody>
        @if (Virtualize)
        {
            <Virtualize Context="item" Items="Items">
                <ItemContent>
                    <tr>@RowTemplate(item)</tr>
                </ItemContent>
                <Placeholder>
                    <p>Loading..</p>
                </Placeholder>
            </Virtualize>
        }
        else
        {
            @foreach (var item in Items)
            {
                <tr>@RowTemplate(item)</tr>
            }
        }
    </tbody>
</table>

TableTemplate.razor.cs:

public partial class TableTemplate<TItem>
{
    [Parameter]
    public string CssClass { get; set; }

    [Parameter]
    public bool Virtualize { get; set; }

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

    [Parameter]
    public RenderFragment<TItem> RowTemplate { get; set; }

    [Parameter]
    public IReadOnlyList<TItem> Items { get; set; }
}

But I'm getting the below error,

The type arguments for method 'TypeInference.CreateVirtualize_0(RenderTreeBuilder, int, int, ICollection, int, RenderFragment, int, RenderFragment)' cannot be inferred from the usage.

How to specify the type if TItem in Virtualize component? Please assist.

1 Answers

TItem is a generic type, so you need to hand it over to the virtualize component (which is also a generic type) like so:

@typeparam TItem

<table class="@CssClass">
    <thead>
        <tr>@TableHeader</tr>
    </thead>
    <tbody>
        @if (Virtualize)
        {
            <Virtualize Context="item" Items="Items" TItem="TItem">
                <ItemContent>
                    <tr>@RowTemplate(item)</tr>
                </ItemContent>
                <Placeholder>
                    <p>Loading..</p>
                </Placeholder>
            </Virtualize>
        }
        else
        {
            @foreach (var item in Items)
            {
                <tr>@RowTemplate(item)</tr>
            }
        }
    </tbody>
</table> 

Also your items cannot be public IReadOnlyList<TItem> Items { get; set; } as you'll get an exception that it can't convert it to an ICollection<TItem>

So that part should be:

    [Parameter]
    public ICollection<TItem> Items { get; set; }
Related