name: telerik description: | USE FOR: Building enterprise .NET applications using Telerik UI components for Blazor, WPF, WinForms, or ASP.NET Core. Use when you need professional-grade data grids, editors, charts, and document processing with commercial support from Progress. DO NOT USE FOR: Open-source-only projects (Telerik requires a commercial license), simple prototypes where a lightweight component library suffices, or game development. license: MIT metadata: displayName: Telerik UI author: "Tyler-R-Kendrick" version: "1.0.0" compatibility:
- claude
- copilot
- cursor references:
- title: "Telerik UI for Blazor Documentation" url: "https://www.telerik.com/blazor-ui/documentation/introduction"
- title: "Telerik UI for Blazor Official Site" url: "https://www.telerik.com/blazor-ui"
Telerik UI
Overview
Telerik UI is a commercial suite of .NET UI components from Progress Software, available for Blazor, WPF, WinForms, and ASP.NET Core. The Telerik UI for Blazor library includes 110+ components covering Data Grid, TreeList, Scheduler, Editor, Charts, Gantt, PDF Viewer, Spreadsheet, and Form components. Telerik components integrate with Blazor Server, Blazor WebAssembly, and .NET 8+ SSR. They provide built-in accessibility (WCAG 2.1), keyboard navigation, localization, and multiple theme options including Material, Bootstrap, Fluent, and Default.
Setup and Registration
Install the Telerik.UI.for.Blazor NuGet package and configure the Telerik service.
using Microsoft.AspNetCore.Components;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorComponents()
.AddInteractiveServerComponents();
builder.Services.AddTelerikBlazor();
var app = builder.Build();
app.UseStaticFiles();
app.UseAntiforgery();
app.MapRazorComponents<App>()
.AddInteractiveServerRenderMode();
app.Run();
Add the TelerikRootComponent in MainLayout.razor:
@inherits LayoutComponentBase
<TelerikRootComponent>
<div class="page">
<main>
@Body
</main>
</div>
</TelerikRootComponent>
Data Grid with Editing and Virtual Scrolling
The TelerikGrid supports inline editing, popup editing, virtual scrolling, and server-side data operations via OnRead.
@page "/products"
@using Telerik.Blazor.Components
@using Telerik.DataSource
@inject IProductService ProductService
<TelerikGrid Data="_products"
TItem="Product"
OnRead="OnGridRead"
Pageable="true"
PageSize="25"
Sortable="true"
FilterMode="GridFilterMode.FilterRow"
EditMode="GridEditMode.Inline"
OnUpdate="OnProductUpdate"
OnDelete="OnProductDelete"
OnCreate="OnProductCreate"
Height="600px"
ScrollMode="GridScrollMode.Virtual"
RowHeight="40">
<GridToolBarTemplate>
<GridCommandButton Command="Add" Icon="@SvgIcon.Plus">Add Product</GridCommandButton>
</GridToolBarTemplate>
<GridColumns>
<GridColumn Field="@nameof(Product.Name)" Title="Product Name" Width="250px" />
<GridColumn Field="@nameof(Product.Category)" Title="Category" Width="180px">
<FilterCellTemplate>
<TelerikDropDownList Data="_categories" @bind-Value="context.FilterDescriptor.Value"
DefaultText="All Categories" />
</FilterCellTemplate>
</GridColumn>
<GridColumn Field="@nameof(Product.Price)" Title="Price" DisplayFormat="{0:C2}" Width="120px" />
<GridColumn Field="@nameof(Product.StockCount)" Title="Stock" Width="100px" />
<GridColumn Field="@nameof(Product.LastUpdated)" Title="Updated"
DisplayFormat="{0:yyyy-MM-dd}" Width="140px" />
<GridCommandColumn Width="200px">
<GridCommandButton Command="Edit" Icon="@SvgIcon.Pencil">Edit</GridCommandButton>
<GridCommandButton Command="Delete" Icon="@SvgIcon.Trash">Delete</GridCommandButton>
<GridCommandButton Command="Save" Icon="@SvgIcon.Save" ShowInEdit="true">Save</GridCommandButton>
<GridCommandButton Command="Cancel" Icon="@SvgIcon.Cancel" ShowInEdit="true">Cancel</GridCommandButton>
</GridCommandColumn>
</GridColumns>
</TelerikGrid>
@code {
private List<Product> _products = new();
private List<string> _categories = new() { "Electronics", "Clothing", "Food", "Books" };
private async Task OnGridRead(GridReadEventArgs args)
{
var result = await ProductService.GetFilteredAsync(args.Request);
args.Data = result.Data;
args.Total = result.Total;
}
private async Task OnProductUpdate(GridCommandEventArgs args)
{
var product = (Product)args.Item;
await ProductService.UpdateAsync(product);
}
private async Task OnProductDelete(GridCommandEventArgs args)
{
var product = (Product)args.Item;
await ProductService.DeleteAsync(product.Id);
}
private async Task OnProductCreate(GridCommandEventArgs args)
{
var product = (Product)args.Item;
await ProductService.CreateAsync(product);
}
}
Charts
Telerik Blazor Charts support bar, column, line, area, pie, donut, funnel, and stock chart types.
@using Telerik.Blazor.Components
<TelerikChart Width="100%" Height="400px">
<ChartTitle Text="Monthly Revenue vs Expenses" />
<ChartSeriesItems>
<ChartSeries Type="ChartSeriesType.Column"
Data="_revenue" Field="Value" CategoryField="Month"
Name="Revenue" Color="#4e79a7" />
<ChartSeries Type="ChartSeriesType.Column"
Data="_expenses" Field="Value" CategoryField="Month"
Name="Expenses" Color="#e15759" />
<ChartSeries Type="ChartSeriesType.Line"
Data="_profit" Field="Value" CategoryField="Month"
Name="Profit" Color="#59a14f" />
</ChartSeriesItems>
<ChartCategoryAxes>
<ChartCategoryAxis>
<ChartCategoryAxisLabels Format="{0}" />
</ChartCategoryAxis>
</ChartCategoryAxes>
<ChartValueAxes>
<ChartValueAxis>
<ChartValueAxisLabels Format="${0:N0}" />
</ChartValueAxis>
</ChartValueAxes>
<ChartTooltip Visible="true">
<Template>
@context.FormattedValue
</Template>
</ChartTooltip>
<ChartLegend Position="ChartLegendPosition.Bottom" />
</TelerikChart>
@code {
private List<ChartDataPoint> _revenue = new()
{
new("Jan", 45000), new("Feb", 52000), new("Mar", 61000),
new("Apr", 58000), new("May", 67000), new("Jun", 72000)
};
private List<ChartDataPoint> _expenses = new()
{
new("Jan", 32000), new("Feb", 35000), new("Mar", 38000),
new("Apr", 36000), new("May", 41000), new("Jun", 39000)
};
private List<ChartDataPoint> _profit = new()
{
new("Jan", 13000), new("Feb", 17000), new("Mar", 23000),
new("Apr", 22000), new("May", 26000), new("Jun", 33000)
};
public record ChartDataPoint(string Month, decimal Value);
}
Scheduler
The Telerik Scheduler provides day, week, month, timeline, and agenda views with drag-and-drop appointment management.
@using Telerik.Blazor.Components
<TelerikScheduler Data="_appointments"
@bind-Date="_selectedDate"
@bind-View="_selectedView"
Height="700px"
AllowCreate="true"
AllowUpdate="true"
AllowDelete="true"
OnCreate="OnAppointmentCreate"
OnUpdate="OnAppointmentUpdate"
OnDelete="OnAppointmentDelete"
IdField="@nameof(SchedulerAppointment.Id)"
TitleField="@nameof(SchedulerAppointment.Title)"
StartField="@nameof(SchedulerAppointment.Start)"
EndField="@nameof(SchedulerAppointment.End)"
IsAllDayField="@nameof(SchedulerAppointment.IsAllDay)"
RecurrenceRuleField="@nameof(SchedulerAppointment.RecurrenceRule)">
<SchedulerViews>
<SchedulerDayView StartTime="@new TimeSpan(8, 0, 0)"
EndTime="@new TimeSpan(18, 0, 0)" />
<SchedulerWeekView StartTime="@new TimeSpan(8, 0, 0)"
EndTime="@new TimeSpan(18, 0, 0)" />
<SchedulerMonthView />
</SchedulerViews>
</TelerikScheduler>
@code {
private DateTime _selectedDate = DateTime.Today;
private SchedulerView _selectedView = SchedulerView.Week;
private List<SchedulerAppointment> _appointments = new();
private async Task OnAppointmentCreate(SchedulerCreateEventArgs args)
{
var appointment = (SchedulerAppointment)args.Item;
appointment.Id = Guid.NewGuid();
_appointments.Add(appointment);
await AppointmentService.CreateAsync(appointment);
}
private async Task OnAppointmentUpdate(SchedulerUpdateEventArgs args)
{
var appointment = (SchedulerAppointment)args.Item;
var index = _appointments.FindIndex(a => a.Id == appointment.Id);
if (index >= 0) _appointments[index] = appointment;
await AppointmentService.UpdateAsync(appointment);
}
private async Task OnAppointmentDelete(SchedulerDeleteEventArgs args)
{
var appointment = (SchedulerAppointment)args.Item;
_appointments.Remove(appointment);
await AppointmentService.DeleteAsync(appointment.Id);
}
}
Telerik vs Other Component Suites
| Feature | Telerik | DevExpress | Syncfusion | Radzen |
|---|---|---|---|---|
| License | Commercial | Commercial | Commercial + community | Free + IDE |
| Blazor components | 110+ | 80+ | 80+ | 90+ |
| Grid virtual scroll | Yes | Yes | Yes | Yes |
| Document processing | Yes (PDF, Word, Excel) | Yes (XtraReports) | Yes | No |
| Scheduler | Yes | Yes | Yes | Yes |
| Gantt chart | Yes | No | Yes | No |
| Theme builder | Yes (ThemeBuilder) | Yes | Yes | Yes |
Best Practices
Use the
OnReadevent withDataSourceRequestfor all grid data operations instead of binding aList<T>to theDataparameter, becauseOnReadpasses sorting, filtering, paging, and grouping descriptors that can be translated server-side usingTelerik.DataSource.Extensions.ToDataSourceResult()on anIQueryable<T>.Wrap the entire application in
<TelerikRootComponent>inMainLayout.razorrather than placing it on individual pages, because Telerik dialogs, context menus, and tooltips render at the root level and fail to display if the root component is missing or nested incorrectly.Set
Fieldon grid columns usingnameof()expressions (e.g.,Field="@nameof(Product.Name)") instead of hardcoded strings, so that property renames on the model class produce compile-time errors rather than silently rendering empty cells.Configure
ScrollMode="GridScrollMode.Virtual"with an explicitRowHeightfor grids displaying more than 500 rows, and ensure theHeightproperty is set to a fixed pixel value; virtual scrolling requires a known row height to calculate the scrollbar position and only renders visible rows in the DOM.Use
DisplayFormaton grid columns for date and numeric formatting (e.g.,"{0:C2}","{0:yyyy-MM-dd}") rather than a<Template>withToString(), becauseDisplayFormatis applied in export, group headers, and aggregate footers.Define
<GridCommandColumn>buttons withShowInEdit="true"for Save/Cancel and without it for Edit/Delete, so that the correct button set appears based on whether the row is in read or edit mode; combining all four buttons withoutShowInEditflags shows all actions simultaneously.Register the Telerik NuGet feed in
nuget.configusing the private feed URL and API key stored in CI secrets (https://nuget.telerik.com/v3/index.json), and never commit the API key to source control; the feed requires an active Telerik license.Use the Telerik ThemeBuilder (
themebuilder.telerik.com) to generate custom SCSS overrides and include the compiled CSS as a static asset, rather than overriding Telerik CSS classes directly; direct overrides break on version upgrades when internal class names change.Handle Scheduler
OnCreate,OnUpdate, andOnDeleteevents by mutating the bound collection and persisting to the database in the same handler, because the Scheduler does not automatically add/update items in the data source; if you persist but forget to update the in-memory list, the appointment disappears until the next data refresh.Set
Debouncedelay onTelerikTextBoxfilter inputs bound to gridFilterCellTemplate(e.g.,DebounceDelay="300") to avoid triggering a server-sideOnReadcall on every keystroke; without debouncing, rapid typing causes a flood of concurrentOnReadinvocations that degrade Blazor Server circuit responsiveness.