Search code examples
c#entity-framework-coreblazorquickgrid

Blazor Quickgrid - how to add a row counter when using Virtualise


Using Blazors Quickgrid. I would like to show a row number for the items. They are 'ApplicationUser' Items. (The id is a guid) It looks like this:

            <div class="grid" tabindex="-1">
                <QuickGrid Items="FilteredUsers" Virtualize="true" @ref="_gridview" >
                    <PropertyColumn Property="@(u => u.FirstName)" Sortable="true" />
                    <PropertyColumn Property="@(u => u.LastName)" Sortable="true" Title="Name">
                        <ColumnOptions>
                            <input type="search" autofocus @bind="LastNamefilter" @bind:event="oninput" placeholder="Last Name ..." />
                        </ColumnOptions>
                    </PropertyColumn>
                    .
                    .
                    .
                    more stuff..

The 'FilteredUsers' comes from:


        private IQueryable<ApplicationUser> FilteredUsers;

        private void UpdateUsers()
        {
            FilteredUsers = _rgContext.Users.Where(u => u.LastName!.Contains(LastNamefilter)
             && u.Email!.Contains(Emailfilter)
             && u.PhoneNumber!.Contains(Phonefilter)
             );
            totalcount = FilteredUsers.Count();
        }

The _rgcontext is created using a contextFactory created in the OnInit function:

        protected override async Task  OnInitializedAsync()
        {
            _rgContext = _contextFactory.CreateDbContext();
            await _userService.CheckUpdateCurrentUserInfo();
            UpdateUsers();
            await base.OnInitializedAsync();
            return;
        }

... and disposed: (THough not sure if this is relevant... seems to work so far.

        public void Dispose()
        {
            _rgContext?.Dispose();
        }

I have the totalcount value from the query. But I would like to add a row number. I can't seem to find anywhere I can (say) get a callback to create a column with such a number in it.. Any thoughts?


Solution

  • Easiest option is to use an ItemsProvider. I find that works better for large datasets with EF anyway.

    An ItemsProvider is a callback with a request parameter. You can use request.StartIndex to base your numbering upon. You'll probably want to wrap the entities with a ViewModel to store the number.

    Basic idea:

    
    GridItemsProvider<TblAddress>? itemsProvider;
    Dictionary<TblAddress, int> rownumLookup = new();
    int? GetRowNum(TblAddress e) => rownumLookup.TryGetValue(e, out int row) ? row : null;
    
    protected override async Task OnInitializedAsync()
    {        
        itemsProvider = async request =>
        {
            using var dbContext = CtxFactory.CreateDbContext();
    
            var query = dbContext.TblAddresses.AsNoTracking();
            query = ApplyFilters(query);
    
            var result = new GridItemsProviderResult<TblAddress>
                {
                    TotalItemCount = await query.CountAsync(request.CancellationToken),
    
                    Items = await request.ApplySorting(query)
                                        .Skip(request.StartIndex)
                                        .Take(request.Count ?? 100)
                                        .ToListAsync(request.CancellationToken),
                };
    
            rownumLookup = result.Items
            .Select((TblAddress e, int n) => ( e, n ))
            .ToDictionary(t => t.e, t => request.StartIndex + t.n);
    
            return result;
        };
    }