RadzenGrid does not show any data

Hello everyone, this is my first implementation of a Radzen component. I have a Radzen component that is not showing anything. I have included a div with a foreach loop that iterates through all the elements of the component and this does show the data, so the problem is obviously in the configuration of the component. Can anyone tell me what I am doing wrong?

@page "/pnd"
@using Sigea.Modelo.Models;
@inject IAsistenciaSigeaService asistenciaService
@inject IPNDService PNDService
@using System.Collections.ObjectModel;

<h1>Personal no docente</h1>

<RadzenGrid TItem="PND_HORAS" Data="@listaPndHoras">
    <RadzenGridColumn TItem="PND_HORAS" Title="Nombre">
        <Template Context="pndHoras">
            @pndHoras.Personal.Nombre
        </Template>
    </RadzenGridColumn>
    <RadzenGridColumn TItem="PND_HORAS" Title="Días trabajados">
        <Template Context="pndHoras">
            @pndHoras.DiasTrabajados
        </Template>
    </RadzenGridColumn>
    <RadzenGridColumn TItem="PND_HORAS" Title="Horas trabajadas">
        <Template Context="pndHoras">
            @pndHoras.HorasTrabajadas
        </Template>
    </RadzenGridColumn>
</RadzenGrid>
<div>
    <p>
        @{
            foreach (PND_HORAS item in listaPndHoras)
            {
                <a>Nombre: @item.Personal.Nombre</a>
            }
        }
    </p>
</div>

@code {
    List<PersonalNoDocente> personalNoDocentes;
    ObservableCollection<PND_HORAS> listaPndHoras = new ObservableCollection<PND_HORAS>();
    protected override async Task OnInitializedAsync()
    {
        // Obtener los datos de la entidad PersonalNoDocente
        personalNoDocentes = await PNDService.TraerLista();

        foreach (var pnd in personalNoDocentes)
        {
            var diasTrabajados = await asistenciaService.CalcularDiasTrabajadosAsync(pnd.Id, DateTime.Now.Month, DateTime.Now.Year);
            var horasTrabajadas = await asistenciaService.CalcularHorasTrabajadasAsync(pnd.Id, DateTime.Now.Month, DateTime.Now.Year);
            var saldoHorario = asistenciaService.CalcularDiferenciaHoras(horasTrabajadas, diasTrabajados);
            var pndHoras = new PND_HORAS
                {
                    Personal = pnd,
                    DiasTrabajados = diasTrabajados,
                    HorasTrabajadas = horasTrabajadas,
                    SaldoHorario = saldoHorario
                };
            listaPndHoras.Add(pndHoras);
            StateHasChanged();
        }
    }
    public class PND_HORAS
    {
        public PersonalNoDocente Personal { get; set; }
        public int DiasTrabajados { get; set; }
        public TimeSpan HorasTrabajadas { get; set; }
        public TimeSpan SaldoHorario { get; set; }
    }
}

Try move the StateHasChanged(); to after the loop

Edit: I have a similar grid, only diff is I use <RadzenDataGrid> instead and I get the grid updated even without the StateHasChanged()

Thanks for your quick response. the result was the same

Can you instead try InvokeAsync(StateHasChanged);?

IMHO you should direct assign new instance to the collection bound to the DataGrid Data property. Nothing will notify the DataGrid that you are adding items to the collection.

I'm not sure if I did what you told me correctly, but the result is the same.

What I did was replace
StateHasChanged();
for :
await InvokeAsync(StateHasChanged);

After the end of the loop.

Sorry, could you explain a little more, I'm pretty new to blazor.

Thanks for trying to help me.

Adding items to ObservableCollection<T> after the DataGrid is bound will not have the expected result since our DataGrid will not listen to INotifyCollectionChanged.CollectionChanged.

This is really interesting. I tried instantiating a ObservableCollection<T> and fill it just like @niodetark does and it does not render the items.

It does however work to convert it to List<T>.

<RadzenGrid TItem="PND_HORAS" Data="listaPndHoras.ToList()">

I would however not do the converting there, this was just for testing purposes mainly.

Thanks @enchev, learned something new today :+1:

1 Like

unfortunately it still has the same behavior

@niodetark If you try this, does it still not work?


@page "/pnd"
@using Sigea.Modelo.Models;
@inject IAsistenciaSigeaService asistenciaService
@inject IPNDService PNDService
@using System.Collections.ObjectModel;

<h1>Personal no docente</h1>

<RadzenGrid TItem="PND_HORAS" Data="listaPndHoras2">
    <RadzenGridColumn TItem="PND_HORAS" Title="Nombre">
        <Template Context="pndHoras">
            @pndHoras.Personal.Nombre
        </Template>
    </RadzenGridColumn>
    <RadzenGridColumn TItem="PND_HORAS" Title="Días trabajados">
        <Template Context="pndHoras">
            @pndHoras.DiasTrabajados
        </Template>
    </RadzenGridColumn>
    <RadzenGridColumn TItem="PND_HORAS" Title="Horas trabajadas">
        <Template Context="pndHoras">
            @pndHoras.HorasTrabajadas
        </Template>
    </RadzenGridColumn>
</RadzenGrid>
<div>
    <p>
        @{
            foreach (PND_HORAS item in listaPndHoras)
            {
                <a>Nombre: @item.Personal.Nombre</a>
            }
        }
    </p>
</div>

@code {
    List<PersonalNoDocente> personalNoDocentes;
    ObservableCollection<PND_HORAS> listaPndHoras = new ObservableCollection<PND_HORAS>();
    List<PND_HORAS> listaPndHoras2 = new List<PND_HORAS>();
    protected override async Task OnInitializedAsync()
    {
        // Obtener los datos de la entidad PersonalNoDocente
        personalNoDocentes = await PNDService.TraerLista();

        foreach (var pnd in personalNoDocentes)
        {
            var diasTrabajados = await asistenciaService.CalcularDiasTrabajadosAsync(pnd.Id, DateTime.Now.Month, DateTime.Now.Year);
            var horasTrabajadas = await asistenciaService.CalcularHorasTrabajadasAsync(pnd.Id, DateTime.Now.Month, DateTime.Now.Year);
            var saldoHorario = asistenciaService.CalcularDiferenciaHoras(horasTrabajadas, diasTrabajados);
            var pndHoras = new PND_HORAS
                {
                    Personal = pnd,
                    DiasTrabajados = diasTrabajados,
                    HorasTrabajadas = horasTrabajadas,
                    SaldoHorario = saldoHorario
                };
            listaPndHoras.Add(pndHoras);
            listaPndHoras2.Add(pndHoras);
        }
    }
    public class PND_HORAS
    {
        public PersonalNoDocente Personal { get; set; }
        public int DiasTrabajados { get; set; }
        public TimeSpan HorasTrabajadas { get; set; }
        public TimeSpan SaldoHorario { get; set; }
    }
}

This expression will be evaluated on every state change of the page and that's why it works. It creates also new instance each time and assigns Data. Assigning Data is the only way to show anything in our DataGrid.

1 Like

Yes, I am aware and that's why I wrote this below it:

I would however not do the converting there, this was just for testing purposes mainly.

In the code I provided in the next reply I created a new class variable instead that is a List<T>

hi every one, sorry for delay

Hello everyone, sorry for answering just now, on Friday I finished my workday and I no longer had access to my computer. I'm sorry to inform you that I made the changes and still nothing appears. This time, I manage to see for a second a legend that says "no record to display"

Strange.. but I have a couple of other suggestions you could try.

  1. Try calling the Reload() method on the RadzenGrid component after the data is loaded.
  2. Swap RadzenGrid with RadzenDataGrid.

To be frank I'm pretty new to Radzen and I'm not sure what the difference between RadzenGrid and RadzenDataGrid is. They seem to be doing the same kind of thing but RadzenDataGrid seems more potent and I can't find much about RadzenGrid in the documentation outside of GitHub. All examples and whatnot seem to use RadzenDataGrid.

Perhaps @enchev can shed some light on why there are two seemingly similar components?

Try this and it should work:

listaPndHoras2 = listaPndHoras.ToList();

Radzen.Blazor components check if the value of their Data property has changed. This requires the instance of listaPndHoras2 to actually change which is what listaPndHoras.ToList() does. Otherwise the value remains the same and calling Reload() would be needed.

RadzenGrid is the older version and we consider it obsolete. RadzenDataGrid is the newer version that we actively maintain. However both RadzenGrid and RadzenDataGrid behave the same when it comes to handing Data changes.

Here is another example:

<RadzenDataGrid Data=@data>

@code {
    private List<DataItem> data = new List<DataItem>();
    protected override async Task OnInitializedAsync()
    {
        data.Add(new DataItem());  // Won't will be displayed as data remains the same instance
    }
}
<RadzenDataGrid Data=@data>

@code {
    private List<DataItem> data = new List<DataItem>();
    protected override async Task OnInitializedAsync()
    {
        data = new List<DataItem> { new DataItem() };  // Will display as data changes to a new instance
    }
}
1 Like

Hello, I still have the same result.
How can I know if the Radzen component is well registered? Is there a way to simulate some data to know if it appears?
PS: I had already changed to radzenDataGrid

Why have my post been closed? I still haven't solved the problem.

Post your latest code. Probably you are still not updating the required property.