Rebind Grid from Timer
Environment
Product |
AutoComplete for Blazor, ComboBox for Blazor, DropDownList for Blazor, Grid for Blazor, ListView for Blazor, MultiColumnComboBox for Blazor, MultiSelect for Blazor, TreeList for Blazor, TreeView for Blazor |
Description
How to rebind a Grid component from a Timer?
How to refresh the component data after a few seconds with a Timer?
Solution
- Use a
System.Timers.Timer
. - Define an
Elapsed
event handler. - When binding via
Data
parameter, theElapsed
event handler should reset the collection reference or call theRebind
method of the component(s). - When binding via
OnRead
event, theElapsed
event handler should call theRebind
method of the component(s) viaInvokeAsync
. - Be aware of Blazor Tread Safety.
@using System.Timers
@using Telerik.DataSource.Extensions
@implements IDisposable
<h1>Rebind with Timer</h1>
<TelerikButton ThemeColor="@ThemeConstants.Button.ThemeColor.Primary"
OnClick="@RebindComponents">Rebind Manually</TelerikButton>
or wait 2 seconds...
<br />
<br />
The first data item is: @DropDownData.FirstOrDefault()?.Text
<TelerikStackLayout Orientation="@StackLayoutOrientation.Horizontal" Spacing="20px">
<div>
<h2>OnRead Event</h2>
<TelerikDropDownList @ref="@DropDownRef"
OnRead="@OnDropDownRead"
TItem="@SampleModel"
TValue="@int"
@bind-Value="@DropDownValue"
ValueField="@nameof(SampleModel.Id)"
TextField="@nameof(SampleModel.Text)"
Width="200px">
<ValueTemplate>
@context.Id : @context.Text
</ValueTemplate>
<ItemTemplate>
@context.Id : @context.Text
</ItemTemplate>
</TelerikDropDownList>
<br /><br />
<TelerikGrid @ref="@GridRef"
OnRead="@OnGridRead"
TItem="@SampleModel"
AutoGenerateColumns="true"
Sortable="true"
Pageable="true"
PageSize="3"
Width="90%" />
</div>
<div>
<h2>Data Parameter</h2>
<TelerikDropDownList Data="@DropDownData"
TItem="@SampleModel"
TValue="@int"
@bind-Value="@DropDownValue"
ValueField="@nameof(SampleModel.Id)"
TextField="@nameof(SampleModel.Text)"
Width="200px">
<ValueTemplate>
@context.Id : @context.Text
</ValueTemplate>
<ItemTemplate>
@context.Id : @context.Text
</ItemTemplate>
</TelerikDropDownList>
<br /><br />
<TelerikGrid Data="@GridData"
TItem="@SampleModel"
AutoGenerateColumns="true"
Sortable="true"
Pageable="true"
PageSize="3"
Width="90%" />
</div>
</TelerikStackLayout>
@code {
private TelerikGrid<SampleModel> GridRef { get; set; }
private TelerikDropDownList<SampleModel, int> DropDownRef { get; set; }
private List<SampleModel> GridData { get; set; }
private List<SampleModel> DropDownData { get; set; }
private int DropDownValue { get; set; } = 1;
private Timer Timer { get; set; } = new Timer();
private void RebindComponents()
{
GenerateData();
GridRef.Rebind();
DropDownRef.Rebind();
}
private async Task OnGridRead(GridReadEventArgs args)
{
await Task.Delay(100); // simulate network delay
var result = GridData.ToDataSourceResult(args.Request);
args.Data = result.Data;
args.Total = result.Total;
}
private async Task OnDropDownRead(DropDownListReadEventArgs args)
{
await Task.Delay(100); // simulate network delay
var result = DropDownData.ToDataSourceResult(args.Request);
args.Data = result.Data;
args.Total = result.Total;
}
protected override void OnAfterRender(bool firstRender)
{
if (Timer.Enabled == false)
{
Timer.Interval = 2000;
Timer.Elapsed -= OnTimerElapsed;
Timer.Elapsed += OnTimerElapsed;
Timer.Start();
}
}
private void OnTimerElapsed(Object source, ElapsedEventArgs e)
{
// the OnRead binding mechanism requires InvokeAsync
InvokeAsync(RebindComponents);
// call StateHasChanged only if necessary
//InvokeAsync(StateHasChanged);
}
private void GenerateData()
{
GridData = new List<SampleModel>();
DropDownData = new List<SampleModel>();
var rnd = new Random();
for (int i = 1; i <= 10; i++)
{
var rndNumber = rnd.Next(1, 100);
GridData.Add(new SampleModel() { Id = i, Text = $"Text {rndNumber}" });
DropDownData.Add(new SampleModel() { Id = i, Text = $"Text {rndNumber}" });
}
}
protected override void OnInitialized()
{
GenerateData();
base.OnInitialized();
}
public void Dispose()
{
Timer?.Stop();
Timer?.Close();
}
public class SampleModel
{
public int Id { get; set; }
public string Text { get; set; }
}
}
Notes
We recommend using System.Timers.Timer
instead of System.Threading.Timer
in Blazor.
When the DropDownList is bound via Data
, its dropdown will not refresh automatically if it is open during the rebind. This is because all our popups are rendered outside the Razor component that defines them. The limitation does not exist with OnRead
data binding, because then the UI refresh does not rely on the Blazor component life cycle.