Skip to content

Commit 06e25d4

Browse files
github-actions[bot]dimodiTsvetomir-Hr
authored
Merge grid-virtual-revamp-2811 into production (#2818)
* docs(Grid,TreeList): Revamp Virtual Scrolling documentation * Update components/treelist/virtual-scrolling.md Co-authored-by: Tsvetomir Hristov <[email protected]> * Update knowledge-base/grid-virtualization-many-records.md Co-authored-by: Tsvetomir Hristov <[email protected]> * Update knowledge-base/grid-virtualization-many-records.md Co-authored-by: Tsvetomir Hristov <[email protected]> * Update knowledge-base/grid-virtualization-many-records.md Co-authored-by: Tsvetomir Hristov <[email protected]> * Update knowledge-base/grid-virtualization-many-records.md Co-authored-by: Tsvetomir Hristov <[email protected]> * Update components/grid/virtual-scrolling.md Co-authored-by: Tsvetomir Hristov <[email protected]> --------- Co-authored-by: Dimo Dimov <[email protected]> Co-authored-by: Tsvetomir Hristov <[email protected]>
1 parent cfb75fa commit 06e25d4

File tree

7 files changed

+479
-331
lines changed

7 files changed

+479
-331
lines changed

components/grid/manual-operations.md

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ Examples:
2929
* [Telerik .ToDataSourceResult(request)](#telerik-todatasourceresult-request)
3030
* [Grouping with OnRead](#grouping-with-onread)
3131
* [Aggregates with OnRead](#aggregates-with-onread)
32+
* [Virtual Scrolling with OnRead](#virtual-scrolling-with-onread)
3233
* [Get Information From the DataSourceRequest](#get-information-from-the-datasourcerequest)
3334
* [Use OData Service](https://github.com/telerik/blazor-ui/tree/master/grid/odata)
3435
* [Serialize the DataSoureRequest to the server](https://github.com/telerik/blazor-ui/tree/master/grid/datasourcerequest-on-server)
@@ -277,9 +278,7 @@ This sample shows how to set up the grid to use grouping with manual data source
277278

278279
When using [aggregates](slug:grid-aggregates) with `OnRead`, the Grid expects you to set one more property of the `GridReadEventArgs` object - `AggregateResults`. Otherwise the component will show aggregate values for the current page only.
279280

280-
<div class="skip-repl"></div>
281-
282-
````CS
281+
````C#.skip-repl
283282
private async Task OnGridRead(GridReadEventArgs args)
284283
{
285284
DataSourceResult result = AllGridData.ToDataSourceResult(args.Request);
@@ -290,6 +289,19 @@ private async Task OnGridRead(GridReadEventArgs args)
290289
}
291290
````
292291

292+
## Virtual Scrolling with OnRead
293+
294+
When using [virtual Grid scrolling](slug:components/grid/virtual-scrolling), get the values of `args.Request.Skip` and `args.Request.PageSize` to determine the current Grid scroll offset and load the correct data items. Do not use `args.Request.Page` with virtual scrolling, because it is always `1`.
295+
296+
````C#.skip-repl
297+
private List<Product> GridData { get; set; } = new();
298+
299+
private async Task OnGridRead(GridReadEventArgs args)
300+
{
301+
args.Data = GridData.Skip(args.Request.Skip).Take(args.Request.PageSize);
302+
args.Total = GridData.Count;
303+
}
304+
````
293305

294306
## Get Information From the DataSourceRequest
295307

components/grid/virtual-scrolling.md

Lines changed: 93 additions & 253 deletions
Large diffs are not rendered by default.

components/treelist/virtual-scrolling.md

Lines changed: 133 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -3,93 +3,179 @@ title: Virtual Scrolling
33
page_title: TreeList - Virtual Scrolling
44
description: Enable and configure the virtual scrolling of rows in the TreeList for Blazor.
55
slug: treelist-virtual-scrolling
6-
tags: telerik,blazor,treelist,virtual,rows,scrolling
6+
tags: telerik,blazor,treelist,virtual,scrolling
77
published: True
88
position: 25
99
---
1010

1111
# TreeList Virtual Scrolling
1212

13+
The TreeList virtual scrolling feature allows users to scroll vertically through all records in the data source. The feature is an alternative to paging.
1314

14-
Virtual scrolling provides an alternative to paging. Instead of utilizing a pager, the user scrolls vertically through all records in the data source.
15+
To enhance the rendering performance, the TreeList reuses the same set of HTML elements. Loading indicators (skeletons) appear in the table cells during scrolling and data loading. If the user scrolls back up after scrolling down to the next set of rows, the previous data reloads from the data source, similar to regular paging, with the scroll distance determining the data to be loaded.
1516

16-
To enhance rendering performance, the TreeList reuses the same set of HTML elements. As the next data loads, a loading indicator appears on the cells. If the user scrolls back up after scrolling down to the next set of rows, the previous data reloads from the data source, similar to regular paging, with the scroll distance determining the data to be loaded.
17+
You can also use the [Blazor TreeList virtualization for the TreeList columns](slug:treelist-columns-virtual).
1718

1819
## Using Virtual Scrolling
1920

20-
* Set the `ScrollMode` parameter to `TreeListScrollMode.Virtual` (the default value is `Scrollable`).
21-
* Set the `Height` and `RowHeight` parameters.
21+
To enable Blazor TreeList row virtualization:
2222

23-
>caption Enable virtual scrolling in the Telerik TreeList for Blazor
23+
1. Set the `ScrollMode` parameter to `TreeListScrollMode.Virtual` (the default value is `Scrollable`).
24+
1. [Set the `Height` parameter](#height) to a `string` CSS value.
25+
1. [Set the `RowHeight` parameter](#rowheight) to a `decimal` value that denotes pixels.
26+
1. [Set the `PageSize` parameter](#pagesize).
27+
28+
> The values of the `Height`, `RowHeight`, and `PageSize` parameters are related to one another. The following sections explain how.
29+
30+
## Height
31+
32+
Set the TreeList `Height` parameter to any [valid `string` CSS value](slug:common-features/dimensions), for example, `px`, `%`, `em`, or `vh`. If the TreeList should expand vertically, accoding to the available space, then check the article [Adjust Grid Height to Match the Browser Viewport Height](slug:grid-kb-adjust-height-with-browser).
33+
34+
Set the `Height` value, so that users can't see the whole [`PageSize` of items](#pagesize) at once. Otherwise, empty row skeletons may display in the TreeList while users are not scrolling.
35+
36+
## PageSize
37+
38+
Set the TreeList `PageSize` parameter to an `int` value. The `PageSize` determines how many table rows are populated and rendered at any given time.
39+
40+
Set the `PageSize` value, so that the rendered table rows do fit in the [TreeList height](#height). At least one table row must be completely invisible. Otherwise, empty row skeletons may display in the TreeList while users are not scrolling. The exact `PageSize` value allows you to balance between better user experience and rendering efficiency:
41+
42+
* A larger `PageSize` value will make the TreeList display empty row skeletons more rarely while users are scrolling down. At the same time, the TreeList may be re-rendering the same data items repetitively if the user scrolls just a little.
43+
* A smaller `PageSize` will make the TreeList render a smaller number of items on each user scroll. At the same time, users will see row skeletons sooner or more frequently during scrolling.
44+
45+
## RowHeight
46+
47+
Set the `RowHeight` parameter to a `decimal` value. The TreeList uses it to set an inline `height` style in pixels to all TreeList table rows (`<tr>`).
48+
49+
The `RowHeight` value must be large enough to accommodate the cell content in all rows, even if the content differs. In other words, the `RowHeight` setting must apply the same or greater table row height than what the browser would normally render. The effective row height depends on:
50+
51+
* The cell content and text wrapping
52+
* The CSS theme, including font size, line height, and cell paddings.
53+
54+
For example, the following list shows the minimum valid `RowHeight` values when using the [built-in CSS themes](slug:themes-overview), single-line plain text content, and no command buttons:
55+
56+
* `36` for the Default theme (`14px` font size, `20px` line height, and 2 * `8px` vertical paddings)
57+
* `40` for the Bootstrap theme (`16px` font size, `24px` line height, and 2 * `8px` vertical paddings)
58+
* `48` for the Material theme (`14px` font size, `28px` line height, and 2 * `10px` vertical paddings)
59+
* `44` for the Fluent theme (`14px` font size, `20px` font size and 2 * `12px` vertical paddings)
60+
61+
> Browsers treat table row `height` styles as `min-height` styles. If the table row content cannot fit in the set `RowHeight`, the browser expands the table row. The TreeList configuration must not allow this to happen. It is crucial that all TreeList table rows display with the same effective height when using virtial scrolling, otherwise the virtual scrolling experience will break.
62+
63+
The `RowHeight` parameter value cannot change at runtime, unless the application recreates the whole TreeList component by removing it from the web page temporarily.
64+
65+
If necessary, you can also use the `RowHeight` parameter without virtual row scrolling.
66+
67+
## Limitations
68+
69+
There is a [browser limitation, which affects the maximum number of data items in a virtual TreeList](slug:grid-kb-virtualization-many-records). The problem occurs with millions of items and you can partially mitigate it by [changing the TreeList styles to make the row height smaller](slug:grid-kb-reduce-row-height).
70+
71+
In addition to virtual scrolling, another approach to optimize the rendering performance is to use [TreeList paging](slug:treelist-paging).
72+
73+
## Example
74+
75+
>caption Virtual TreeList scrolling
2476
2577
````RAZOR
2678
<TelerikTreeList Data="@TreeListData"
27-
ScrollMode="@TreeListScrollMode.Virtual"
28-
Height="500px"
29-
RowHeight="50"
3079
IdField="@nameof(Employee.Id)"
3180
ParentIdField="@nameof(Employee.ParentId)"
32-
Sortable="true"
33-
FilterMode="@TreeListFilterMode.FilterMenu">
81+
FilterMode="TreeListFilterMode.FilterMenu"
82+
Height="360px"
83+
PageSize="20"
84+
RowHeight="40"
85+
ScrollMode="@TreeListScrollMode.Virtual"
86+
Sortable="true">
3487
<TreeListColumns>
35-
<TreeListColumn Expandable="true" Field="FirstName" Title="First Name" />
36-
<TreeListColumn Field="LastName" Title="Last Name" />
37-
<TreeListColumn Field="Position" />
88+
<TreeListColumn Field="@nameof(Employee.Name)" Expandable="true" />
89+
<TreeListColumn Field="@nameof(Employee.Salary)" DisplayFormat="{0:C2}" Width="160px" />
90+
<TreeListColumn Field="@nameof(Employee.HireDate)" DisplayFormat="{0:d}" Width="160px" />
91+
<TreeListColumn Field="@nameof(Employee.IsDriver)" Width="120px" />
3892
</TreeListColumns>
3993
</TelerikTreeList>
4094
4195
@code {
42-
private List<Employee> TreeListData { get; set; } = new();
96+
private List<Employee>? TreeListData { get; set; }
4397
44-
protected override void OnInitialized()
45-
{
46-
for (int i = 1; i <= 1000; i++)
47-
{
48-
TreeListData.Add(new Employee()
49-
{
50-
Id = i,
51-
ParentId = i <= 3 ? null : i % 3 + 1,
52-
FirstName = "First " + i,
53-
LastName = "Last " + i,
54-
Position = i <= 3 ? "Team Lead" : "Software Engineer"
55-
});
56-
}
98+
private EmployeeService TreeListEmployeeService { get; set; } = new(treeLevelCount: 3, rootItemCount: 10, childItemCount: 20);
5799
58-
base.OnInitialized();
100+
protected override async Task OnInitializedAsync()
101+
{
102+
TreeListData = await TreeListEmployeeService.Read();
59103
}
60104
61105
public class Employee
62106
{
63107
public int Id { get; set; }
64108
public int? ParentId { get; set; }
65-
public string FirstName { get; set; }
66-
public string LastName { get; set; }
67-
public string Position { get; set; }
109+
public bool HasChildren { get; set; }
110+
public string Name { get; set; } = string.Empty;
111+
public decimal? Salary { get; set; }
112+
public DateTime? HireDate { get; set; }
113+
public bool IsDriver { get; set; }
68114
}
69-
}
70-
````
71-
72-
## Notes
73115
74-
There are several things to keep in mind when using virtual scrolling:
116+
#region Data Service
75117
76-
* The `RowHeight` is a decimal value that is always interpreted as pixels. The TreeList `Height` does not have to be in pixels, but it may help you calculate the `PageSize` (see below).
118+
public class EmployeeService
119+
{
120+
private List<Employee> Items { get; set; } = new();
77121
78-
* If the row/cell height the browser renders is larger than the `RowHeight` value, the browser will ignore it. It can depend on the chosen Theme, other CSS rules, or cell data that occupies more than one row. Inspect the rendered HTML to make sure the grid setting matches the rendering.
122+
private readonly int TreeLevelCount;
123+
private readonly int RootItemCount;
124+
private readonly int ChildItemCount;
79125
80-
The default TreeList rendering has padding in the cells, and the loading sign has a line height set in order to render. This may impose some minimum heights that can vary with the theme and/or custom styles on the page.
126+
private int LastId { get; set; }
127+
private Random Rnd { get; set; } = Random.Shared;
81128
82-
* The `RowHeight` must not change at runtime, because the new dimensions will cause issues with the scrolling logic.
129+
public async Task<List<Employee>> Read()
130+
{
131+
await SimulateAsyncOperation();
132+
return Items;
133+
}
83134
84-
* Browser zoom or monitor DPI settings can cause the browser to render different dimensions than the expected and/or non-integer values, which can break the virtualization logic.
135+
private async Task SimulateAsyncOperation()
136+
{
137+
await Task.Delay(100);
138+
}
85139
86-
* Do not mix virtualization with paging, as they are alternatives to the same feature.
140+
private void PopulateChildren(List<Employee> items, int? parentId, int level)
141+
{
142+
int itemCount = level == 1 ? RootItemCount : ChildItemCount;
143+
for (int i = 1; i <= itemCount; i++)
144+
{
145+
int itemId = ++LastId;
146+
items.Add(new Employee()
147+
{
148+
Id = itemId,
149+
ParentId = parentId,
150+
HasChildren = level < TreeLevelCount,
151+
Name = $"Employee Name {itemId}", // {level}-{i}
152+
Salary = Rnd.Next(1_000, 10_000) * 1.23m,
153+
HireDate = DateTime.Today.AddDays(-Rnd.Next(365, 3650)),
154+
IsDriver = itemId % 2 == 0
155+
});
156+
if (level < TreeLevelCount)
157+
{
158+
PopulateChildren(items, itemId, level + 1);
159+
}
160+
}
161+
}
87162
88-
* Provide for a `PageSize` of the TreeList that is large enough, so that the loaded table rows do not fit in the scrollable data area, otherwise the vertical virtual scrollbar will not be created and scrolling will not work. To do this, take into account the `Height` of the TreeList and the `RowHeight`.
163+
public EmployeeService(int treeLevelCount = 3, int rootItemCount = 3, int childItemCount = 2)
164+
{
165+
TreeLevelCount = treeLevelCount;
166+
RootItemCount = rootItemCount;
167+
ChildItemCount = childItemCount;
168+
List<Employee> items = new();
169+
PopulateChildren(items, null, 1);
170+
Items = items;
171+
}
172+
}
89173
90-
* The `PageSize` controls how many rows are rendered at any given time, and how many items are requested from the data source when loading data on demand. You should avoid setting large page sizes, you need to only fill up the TreeList data viewport.
174+
#endregion Data Service
175+
}
176+
````
91177

92178
## See Also
93179

94-
* [Live Demo: TreeList Virtual Scrolling](https://demos.telerik.com/blazor-ui/treelist/virtual-scrolling)
95-
180+
* [Live Demo: TreeList Virtual Scrolling](https://demos.telerik.com/blazor-ui/treelist/virtual-scrolling)
181+
* [How to Disable Row Placeholders During Virtual Scrolling](slug:grid-kb-hide-virtual-row-skeletons)
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
---
2+
title: Hide Grid Virtual Row Skeletons
3+
description: Learn how to hide / remove / disable the Grid and TreeList cell placeholder skeletons during virtual row scrolling.
4+
type: how-to
5+
page_title: How To Hide Row Skeletons During Virtual Grid Scrolling
6+
slug: grid-kb-hide-virtual-row-skeletons
7+
tags: blazor, grid, treelist, skeleton, styles, css
8+
ticketid: 1658135, 1642794
9+
res_type: kb
10+
---
11+
12+
## Environment
13+
14+
<table>
15+
<tbody>
16+
<tr>
17+
<td>Product</td>
18+
<td>Grid for Blazor, <br /> TreeList for Blazor</td>
19+
</tr>
20+
</tbody>
21+
</table>
22+
23+
## Description
24+
25+
This KB article answers the following questions:
26+
27+
* How to remove the Grid row placeholders during virtual scrolling?
28+
* How to hide the skeletons that appear in empty table cells during virtual scrolling?
29+
* How to disable the Grid cell placeholders?
30+
* How to turn off the Grid loader indicators inside the virtual rows?
31+
32+
## Solution
33+
34+
Apply a `display:none` or `visibility:hidden` CSS style to the `.k-skeleton` selector inside Grid table cells.
35+
36+
>caption Removing placeholder skeletons during virtual Grid scrolling
37+
38+
````RAZOR
39+
<TelerikGrid Data="@GridData"
40+
Height="360px"
41+
PageSize="20"
42+
RowHeight="40"
43+
ScrollMode="@GridScrollMode.Virtual"
44+
Class="no-skeletons">
45+
<GridColumns>
46+
<GridColumn Field="@nameof(Product.Name)" />
47+
<GridColumn Field="@nameof(Product.Price)" DisplayFormat="{0:c2}" />
48+
<GridColumn Field="@nameof(Product.Quantity)" />
49+
</GridColumns>
50+
</TelerikGrid>
51+
52+
<style>
53+
.no-skeletons .k-table-td > .k-skeleton {
54+
display: none;
55+
}
56+
</style>
57+
58+
@code {
59+
private List<Product> GridData { get; set; } = new();
60+
61+
protected override void OnInitialized()
62+
{
63+
for (int i = 1; i <= 1000; i++)
64+
{
65+
GridData.Add(new Product()
66+
{
67+
Id = i,
68+
Name = $"Name {i}",
69+
Price = Random.Shared.Next(1, 100) * 1.23m,
70+
Quantity = Random.Shared.Next(0, 1000)
71+
});
72+
}
73+
}
74+
75+
public class Product
76+
{
77+
public int Id { get; set; }
78+
public string Name { get; set; } = string.Empty;
79+
public decimal Price { get; set; }
80+
public int Quantity { get; set; }
81+
}
82+
}
83+
````
84+
85+
## See Also
86+
87+
* [Virtual Grid Scrolling](slug:components/grid/virtual-scrolling)
88+
* [Virtual TreeList Scrolling](slug:treelist-virtual-scrolling)

0 commit comments

Comments
 (0)