No Matter How Hard I Try I cannot get RadzenDataGrid to call LoadData

HI Team,

I'm trying to get a RadzenDataGrid to use the "LoadData" function, so I can provide a better loading experience in my app, but irrespective of what I try I just cannot get it to work, I've tried using lambdas, function groups, async, non async, I've copied the examples and nada, nothing... the function just never get's called.

I've even broken this out into a separate test project with the absolute latest version from NuGet and still no success.

Right now I have my test code as simple as possible:

and I cannot even get this to work, any guidance you can provide would be much appreciated.

The "PersonTest" class used by it is this:

Just for completeness.

Maybe if you post it as code not as screenshot will be easier for us to test it.

No probs:

@page "/"
@using Tynamix.ObjectFiller

<h1>Bare SSB App</h1>
<!-- <NavLink href="/protected">Protected Page</NavLink> -->

@if (!_dataLoaded)
{
  <div class="spinner-border" style="width: 3rem; height: 3rem;" role="status">
    <span class="visually-hidden">Loading...</span>
  </div>
  <div>Loading please wait...</div>
}

<RadzenDataGrid
  TItem="PersonTest"
  IsLoading="@_dataLoaded"
  Data="@_peopleData"
  Count="@_dataCount"
  Visible="@_dataLoaded"
  LoadData="@LoadData"
  AllowVirtualization="true">

  <EmptyTemplate>
    <p class="w-100 text-danger text-center lead">There are no "Person" records available.</p>
  </EmptyTemplate>

  <Columns>

    <RadzenDataGridColumn
      TItem="PersonTest"
      Property="@nameof(PersonTest.Id)"
      Title="ID"/>

    <RadzenDataGridColumn
      TItem="PersonTest"
      Property="@nameof(PersonTest.FirstName)"
      Title="First Name"/>

    <RadzenDataGridColumn
      TItem="PersonTest"
      Property="@nameof(PersonTest.Surname)"
      Title="Surname"/>

    <RadzenDataGridColumn
      TItem="PersonTest"
      Property="@nameof(PersonTest.EMail)"
      Title="EMail"/>

    <RadzenDataGridColumn
      TItem="PersonTest"
      Property="@nameof(PersonTest.BirthDate)"
      Title="Birth Date"/>

  </Columns>
</RadzenDataGrid>


@code {

  private bool _dataLoaded = false;
  private List<PersonTest> _peopleData;
  private int _dataCount = 0;

  protected override void OnInitialized()
  {
    _peopleData = new List<PersonTest>();
  }

  async Task LoadData(LoadDataArgs args)
  {
    _dataLoaded = false;

    await Task.Run(() =>
    {
      _peopleData.Clear();
      var pFiller = new Filler<PersonTest>();

      for (var count = 0; count < 1000; count++)
      {
        _peopleData.Add(pFiller.Fill(new PersonTest()));
      }
      _dataCount = 1000;
    });

    _dataLoaded = true;
  }

}

You can use code blocks to format your code in the future - check the forum FAQ for reference. I'll let you know my findings.

No probs @enchev , and I did use code blocks.

When copying & pasting from Rider it always wipes formatting like that out, I don't know why, but it does, that's why I use screen shots instead.

VS I don't have a problem with, it paste's as is, rider does not it tries to reformat the existing content to it's own format.

There are three problems with your code:

  1. DataGrid component is not visible initially and will not call LoadData (or any other event):
  1. DataGrid component will not listen to collection changes and will not know that you've added new data to this list (lists are not also INotifyCollectionChanged):
  1. Virtualization is turned on however no height is specified. The DataGrid will attempt to render all items at once:

Here is reworked version of your code:

@page "/datagrid"
<h1>Bare SSB App</h1>

<RadzenDataGrid Style="height:300px"
  TItem="PersonTest"
  Data="@_peopleData"
  Count="@_dataCount"
  LoadData="@LoadData"
  AllowVirtualization="true">

  <EmptyTemplate>
    <p class="w-100 text-danger text-center lead">There are no "Person" records available.</p>
  </EmptyTemplate>

  <Columns>

    <RadzenDataGridColumn
      TItem="PersonTest"
      Property="@nameof(PersonTest.Id)"
      Title="ID"/>

    <RadzenDataGridColumn
      TItem="PersonTest"
      Property="@nameof(PersonTest.FirstName)"
      Title="First Name"/>

    <RadzenDataGridColumn
      TItem="PersonTest"
      Property="@nameof(PersonTest.Surname)"
      Title="Surname"/>

    <RadzenDataGridColumn
      TItem="PersonTest"
      Property="@nameof(PersonTest.EMail)"
      Title="EMail"/>

    <RadzenDataGridColumn
      TItem="PersonTest"
      Property="@nameof(PersonTest.BirthDate)"
      Title="Birth Date"/>

  </Columns>
</RadzenDataGrid>


@code {
    private List<PersonTest> _peopleData;
    private int _dataCount = 0;

    async Task LoadData(LoadDataArgs args)
    {
        var list = new List<PersonTest>();

        await Task.Run(() =>
        {
            list = Enumerable.Range(args.Skip.Value, args.Top.Value).Select(i => new PersonTest() { Id = i }).ToList();
        });

        _peopleData = list;
        _dataCount = 1000;
    }

    public class PersonTest
    {
        public int Id { get; set; }
        public string FirstName { get; set; }
        public string Surname { get; set; }
        public string EMail { get; set; }
        public DateTime BirthDate { get; set; }
    }
}

I've removed DataGrid IsLoading since this will not play well with virtualization where data will be loaded during scroll.

loaddata

Hi Enchev,

Ok I'll go back and try again, I did however initially try those different variations too, IE: having the grid visible, and not having the virtualization turned on, and a few other different combinations, and up until now I have never been able to get it to call dataload to ask for it's data.

The data notification on lists, I'm aware of, but in many places I use a ref to the grid and call "Reload" manually, so the list contents are not really the problem here, the problem was I was not able to get it to call it's load data handler.

Tks
Shawty

Hi Enchev,

so after a bit of analysis, based on your notes it turns out my main problem was in initialising the collection.

Because I was newing up an instance of the list and setting it to 0 items, and because count was at 0 initially, RadzenDataGrid thought it's data was already loaded and therefore did not need anymore.

I figured this out because it worked with virtualisation on, but not with virtualisation off.

As soon as I took out the new statement in my init methods and left it at null, it started to fire as I'd expected, allowing me to put up my own loading indicator.

As for showing the grid while loading, I've solved that by wrapping the grid in a parent container, and adding the following style rule to it:

style="@(_dataLoaded ? "display: block;" : "display: none;")"

This effectively hides the grid, but still allows it to load behind the scenes, then swaps the loading indicator out, replacing it with the grid once the load has finished.

Tks for the assist, got things working the way I'd hoped they would now.

I had the same issue. I was developing drag and drop for the data grid and needed to refresh the data grid from the [JSInvokable] static method that was part of the callback from the javascript drop function. I originally was trying to call the LoadData method from the static method. Never worked. Once I converted most of the component methods to static I was able to refresh my data grid using a static reference to the data grid.

Also had the same issue and looking into the sources, the data has to be NULL ! I usually create an empty list to not get null ref exceptions and this was my issue.


        internal override async Task ReloadOnFirstRender()
        {
            if (firstRender && Visible && (LoadData.HasDelegate && Data == null) && IsVirtualizationAllowed())
            {
                await InvokeLoadData(skip, PageSize);
            }
            else if(settings == null)
            {
                await base.ReloadOnFirstRender();
            }
        }