I use the data RadzenGrid component.
Works great.
I also use SQL Server Service Broker to get notified when something in my table has changed. More info: https://github.com/christiandelbianco/blazor-notification-db-record-change
I use an IQueryable to load the data:
<RadzenGrid @ref="grid0" AllowFiltering="true" AllowPaging="true" AllowSorting="true" FilterCaseSensitivity="FilterCaseSensitivity.CaseInsensitive"
Data="@getClients" TItem="MDGR.Models.Entities.Master.Client">
IEnumerable<MDGR.Models.Entities.Master.Client> _getClients;
protected IEnumerable<MDGR.Models.Entities.Master.Client> getClients
{
get
{
return _getClients;
}
set
{
if (!object.Equals(_getClients, value))
{
_getClients = value;
InvokeAsync(() => { StateHasChanged(); });
}
}
}
public override async System.Threading.Tasks.Task Load()
{
var result = await ClientService.GetAll(new Query { OrderBy = "Name" });
getClients = result;
}
public async Task<IQueryable<Client>> GetAll(Query query = null)
{
var items = _context.Clients.AsQueryable();
...
}
When the client table is changed, for example by another user or a WebJob the Service Broker broadcasts it and my ClientTableChanged
event is triggered.
At this stage I know if a row is inserted, updated or deleted.
Now I can call await InvokeAsync(grid0.Reload);
to let the grid fetch new data from the database. That isn't necessary because I just need to update the rows in the datagrid.
On an insert, it is fine to re-fetch the data from the database.
On an update, I receive the updated record so I should be able to update the row in the datagrid, without getting back to the database.
Also when the record is changed outside the datagrid and I call grid0.Reload()
the changes are not reflected. I need to refresh the whole page to see the changes.
On a delete, I would like to mark the deleted row in the datagrid and disable the row and give it a different color, making it clear to the user somebody else has removed that item.
public override async void ClientTableChanged(object sender,
TableChangeEventArgs<Models.Entities.Master.Client> args)
{
if (args.ChangeType == ChangeType.Insert)
{
// it is OK to re-fetch the data:
await InvokeAsync(grid0.Reload);
}
if (args.ChangeType == ChangeType.Update)
{
// Update list without going back to the database.
// TODO: This doesn't seems to be the proper workflow
using (var enumerator = grid0.Data.GetEnumerator())
{
while (enumerator.MoveNext())
{
var item = enumerator.Current;
if (item.Id == args.NewValue.Id)
{
// Raises an error: The current thread is not associated with the Dispatcher.
await grid0.EditRow(item);
// TODO: How to update the row
await grid0.UpdateRow(args.NewValue);
// TODO: How to color the row:
}
}
}
}
if (args.ChangeType == ChangeType.Delete)
{
// TODO: Color the row red and disable, using the Id: args.NewValue.Id
}
// Triggers a new fetch from the database, which I want to prevent:
// await InvokeAsync(grid0.Reload);
await InvokeAsync(StateHasChanged);
}
What I'm basically looking for it getting direct access to the rows in the datagrid.