Skip to content

Commit 874df6f

Browse files
authored
Collection type approaches for virtualization (#26836)
1 parent 7a9ca58 commit 874df6f

File tree

1 file changed

+66
-6
lines changed

1 file changed

+66
-6
lines changed

aspnetcore/blazor/components/virtualization.md

Lines changed: 66 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ The `Virtualize` component:
6969
* Calculates the number of items to render based on the height of the container and the size of the rendered items.
7070
* Recalculates and rerenders the items as the user scrolls.
7171
* Only fetches the slice of records from an external API that correspond to the current visible region, instead of downloading all of the data from the collection.
72+
* Receives a generic <xref:System.Collections.Generic.ICollection%601> for <xref:Microsoft.AspNetCore.Components.Web.Virtualization.Virtualize%601.Items?displayProperty=nameWithType>. If a non-generic collection supplies the items (for example, a collection of <xref:System.Data.DataRow>), follow the guidance in the [Item provider delegate](#item-provider-delegate) section to supply the items.
7273

7374
The item content for the `Virtualize` component can include:
7475

@@ -78,7 +79,7 @@ The item content for the `Virtualize` component can include:
7879

7980
## Item provider delegate
8081

81-
If you don't want to load all of the items into memory, you can specify an items provider delegate method to the component's <xref:Microsoft.AspNetCore.Components.Web.Virtualization.Virtualize%601.ItemsProvider%2A?displayProperty=nameWithType> parameter that asynchronously retrieves the requested items on demand. In the following example, the `LoadEmployees` method provides the items to the `Virtualize` component:
82+
If you don't want to load all of the items into memory or the collection isn't a generic <xref:System.Collections.Generic.ICollection%601>, you can specify an items provider delegate method to the component's <xref:Microsoft.AspNetCore.Components.Web.Virtualization.Virtualize%601.ItemsProvider%2A?displayProperty=nameWithType> parameter that asynchronously retrieves the requested items on demand. In the following example, the `LoadEmployees` method provides the items to the `Virtualize` component:
8283

8384
```razor
8485
<Virtualize Context="employee" ItemsProvider="@LoadEmployees">
@@ -93,7 +94,7 @@ The items provider receives an <xref:Microsoft.AspNetCore.Components.Web.Virtual
9394

9495
A `Virtualize` component can only accept **one item source** from its parameters, so don't attempt to simultaneously use an items provider and assign a collection to `Items`. If both are assigned, an <xref:System.InvalidOperationException> is thrown when the component's parameters are set at runtime.
9596

96-
The following `LoadEmployees` method example loads employees from an `EmployeeService` (not shown):
97+
The following example loads employees from an `EmployeeService` (not shown):
9798

9899
```csharp
99100
private async ValueTask<ItemsProviderResult<Employee>> LoadEmployees(
@@ -107,6 +108,25 @@ private async ValueTask<ItemsProviderResult<Employee>> LoadEmployees(
107108
}
108109
```
109110

111+
In the following example, a collection of <xref:System.Data.DataRow> is a non-generic collection, so an items provider delegate is used for virtualization:
112+
113+
```razor
114+
<Virtualize Context="row" ItemsProvider="GetRows">
115+
...
116+
</Virtualize>
117+
118+
@code{
119+
...
120+
121+
private ValueTask<ItemsProviderResult<DataRow>> GetRows(ItemsProviderRequest request)
122+
{
123+
return new(new ItemsProviderResult<DataRow>(
124+
dataTable.Rows.OfType<DataRow>().Skip(request.StartIndex).Take(request.Count),
125+
dataTable.Rows.Count));
126+
}
127+
}
128+
```
129+
110130
<xref:Microsoft.AspNetCore.Components.Web.Virtualization.Virtualize%601.RefreshDataAsync%2A?displayProperty=nameWithType> instructs the component to rerequest data from its <xref:Microsoft.AspNetCore.Components.Web.Virtualization.Virtualize%601.ItemsProvider%2A>. This is useful when external data changes. There's usually no need to call <xref:Microsoft.AspNetCore.Components.Web.Virtualization.Virtualize%601.RefreshDataAsync%2A> when using <xref:Microsoft.AspNetCore.Components.Web.Virtualization.Virtualize%601.Items%2A>.
111131

112132
<xref:Microsoft.AspNetCore.Components.Web.Virtualization.Virtualize%601.RefreshDataAsync%2A> updates a `Virtualize` component's data without causing a rerender. If <xref:Microsoft.AspNetCore.Components.Web.Virtualization.Virtualize%601.RefreshDataAsync%2A> is invoked from a Blazor event handler or component lifecycle method, triggering a render isn't required because a render is automatically triggered at the end of the event handler or lifecycle method. If <xref:Microsoft.AspNetCore.Components.Web.Virtualization.Virtualize%601.RefreshDataAsync%2A> is triggered separately from a background task or event, such as in the following `ForcecastUpdated` delegate, call <xref:Microsoft.AspNetCore.Components.ComponentBase.StateHasChanged%2A> to update the UI at the end of the background task or event:
@@ -322,6 +342,7 @@ The `Virtualize` component:
322342
* Calculates the number of items to render based on the height of the container and the size of the rendered items.
323343
* Recalculates and rerenders the items as the user scrolls.
324344
* Only fetches the slice of records from an external API that correspond to the current visible region, instead of downloading all of the data from the collection.
345+
* Receives a generic <xref:System.Collections.Generic.ICollection%601> for <xref:Microsoft.AspNetCore.Components.Web.Virtualization.Virtualize%601.Items?displayProperty=nameWithType>. If a non-generic collection supplies the items (for example, a collection of <xref:System.Data.DataRow>), follow the guidance in the [Item provider delegate](#item-provider-delegate) section to supply the items.
325346

326347
The item content for the `Virtualize` component can include:
327348

@@ -331,7 +352,7 @@ The item content for the `Virtualize` component can include:
331352

332353
## Item provider delegate
333354

334-
If you don't want to load all of the items into memory, you can specify an items provider delegate method to the component's <xref:Microsoft.AspNetCore.Components.Web.Virtualization.Virtualize%601.ItemsProvider%2A?displayProperty=nameWithType> parameter that asynchronously retrieves the requested items on demand. In the following example, the `LoadEmployees` method provides the items to the `Virtualize` component:
355+
If you don't want to load all of the items into memory or the collection isn't a generic <xref:System.Collections.Generic.ICollection%601>, you can specify an items provider delegate method to the component's <xref:Microsoft.AspNetCore.Components.Web.Virtualization.Virtualize%601.ItemsProvider%2A?displayProperty=nameWithType> parameter that asynchronously retrieves the requested items on demand. In the following example, the `LoadEmployees` method provides the items to the `Virtualize` component:
335356

336357
```razor
337358
<Virtualize Context="employee" ItemsProvider="@LoadEmployees">
@@ -346,7 +367,7 @@ The items provider receives an <xref:Microsoft.AspNetCore.Components.Web.Virtual
346367

347368
A `Virtualize` component can only accept **one item source** from its parameters, so don't attempt to simultaneously use an items provider and assign a collection to `Items`. If both are assigned, an <xref:System.InvalidOperationException> is thrown when the component's parameters are set at runtime.
348369

349-
The following `LoadEmployees` method example loads employees from an `EmployeeService` (not shown):
370+
The following example loads employees from an `EmployeeService` (not shown):
350371

351372
```csharp
352373
private async ValueTask<ItemsProviderResult<Employee>> LoadEmployees(
@@ -360,6 +381,25 @@ private async ValueTask<ItemsProviderResult<Employee>> LoadEmployees(
360381
}
361382
```
362383

384+
In the following example, a collection of <xref:System.Data.DataRow> is a non-generic collection, so an items provider delegate is used for virtualization:
385+
386+
```razor
387+
<Virtualize Context="row" ItemsProvider="GetRows">
388+
...
389+
</Virtualize>
390+
391+
@code{
392+
...
393+
394+
private ValueTask<ItemsProviderResult<DataRow>> GetRows(ItemsProviderRequest request)
395+
{
396+
return new(new ItemsProviderResult<DataRow>(
397+
dataTable.Rows.OfType<DataRow>().Skip(request.StartIndex).Take(request.Count),
398+
dataTable.Rows.Count));
399+
}
400+
}
401+
```
402+
363403
<xref:Microsoft.AspNetCore.Components.Web.Virtualization.Virtualize%601.RefreshDataAsync%2A?displayProperty=nameWithType> instructs the component to rerequest data from its <xref:Microsoft.AspNetCore.Components.Web.Virtualization.Virtualize%601.ItemsProvider%2A>. This is useful when external data changes. There's no need to call <xref:Microsoft.AspNetCore.Components.Web.Virtualization.Virtualize%601.RefreshDataAsync%2A> when using <xref:Microsoft.AspNetCore.Components.Web.Virtualization.Virtualize%601.Items%2A>.
364404

365405
## Placeholder
@@ -484,6 +524,7 @@ The `Virtualize` component:
484524
* Calculates the number of items to render based on the height of the container and the size of the rendered items.
485525
* Recalculates and rerenders the items as the user scrolls.
486526
* Only fetches the slice of records from an external API that correspond to the current visible region, instead of downloading all of the data from the collection.
527+
* Receives a generic <xref:System.Collections.Generic.ICollection%601> for <xref:Microsoft.AspNetCore.Components.Web.Virtualization.Virtualize%601.Items?displayProperty=nameWithType>. If a non-generic collection supplies the items (for example, a collection of <xref:System.Data.DataRow>), follow the guidance in the [Item provider delegate](#item-provider-delegate) section to supply the items.
487528

488529
The item content for the `Virtualize` component can include:
489530

@@ -493,7 +534,7 @@ The item content for the `Virtualize` component can include:
493534

494535
## Item provider delegate
495536

496-
If you don't want to load all of the items into memory, you can specify an items provider delegate method to the component's <xref:Microsoft.AspNetCore.Components.Web.Virtualization.Virtualize%601.ItemsProvider%2A?displayProperty=nameWithType> parameter that asynchronously retrieves the requested items on demand. In the following example, the `LoadEmployees` method provides the items to the `Virtualize` component:
537+
If you don't want to load all of the items into memory or the collection isn't a generic <xref:System.Collections.Generic.ICollection%601>, you can specify an items provider delegate method to the component's <xref:Microsoft.AspNetCore.Components.Web.Virtualization.Virtualize%601.ItemsProvider%2A?displayProperty=nameWithType> parameter that asynchronously retrieves the requested items on demand. In the following example, the `LoadEmployees` method provides the items to the `Virtualize` component:
497538

498539
```razor
499540
<Virtualize Context="employee" ItemsProvider="@LoadEmployees">
@@ -508,7 +549,7 @@ The items provider receives an <xref:Microsoft.AspNetCore.Components.Web.Virtual
508549

509550
A `Virtualize` component can only accept **one item source** from its parameters, so don't attempt to simultaneously use an items provider and assign a collection to `Items`. If both are assigned, an <xref:System.InvalidOperationException> is thrown when the component's parameters are set at runtime.
510551

511-
The following `LoadEmployees` method example loads employees from an `EmployeeService` (not shown):
552+
The following example loads employees from an `EmployeeService` (not shown):
512553

513554
```csharp
514555
private async ValueTask<ItemsProviderResult<Employee>> LoadEmployees(
@@ -522,6 +563,25 @@ private async ValueTask<ItemsProviderResult<Employee>> LoadEmployees(
522563
}
523564
```
524565

566+
In the following example, a collection of <xref:System.Data.DataRow> is a non-generic collection, so an items provider delegate is used for virtualization:
567+
568+
```razor
569+
<Virtualize Context="row" ItemsProvider="@GetRows">
570+
...
571+
</Virtualize>
572+
573+
@code{
574+
...
575+
576+
private ValueTask<ItemsProviderResult<DataRow>> GetRows(ItemsProviderRequest request)
577+
{
578+
return new(new ItemsProviderResult<DataRow>(
579+
dataTable.Rows.OfType<DataRow>().Skip(request.StartIndex).Take(request.Count),
580+
dataTable.Rows.Count));
581+
}
582+
}
583+
```
584+
525585
<xref:Microsoft.AspNetCore.Components.Web.Virtualization.Virtualize%601.RefreshDataAsync%2A?displayProperty=nameWithType> instructs the component to rerequest data from its <xref:Microsoft.AspNetCore.Components.Web.Virtualization.Virtualize%601.ItemsProvider%2A>. This is useful when external data changes. There's usually no need to call <xref:Microsoft.AspNetCore.Components.Web.Virtualization.Virtualize%601.RefreshDataAsync%2A> when using <xref:Microsoft.AspNetCore.Components.Web.Virtualization.Virtualize%601.Items%2A>.
526586

527587
<xref:Microsoft.AspNetCore.Components.Web.Virtualization.Virtualize%601.RefreshDataAsync%2A> updates a `Virtualize` component's data without causing a rerender. If <xref:Microsoft.AspNetCore.Components.Web.Virtualization.Virtualize%601.RefreshDataAsync%2A> is invoked from a Blazor event handler or component lifecycle method, triggering a render isn't required because a render is automatically triggered at the end of the event handler or lifecycle method. If <xref:Microsoft.AspNetCore.Components.Web.Virtualization.Virtualize%601.RefreshDataAsync%2A> is triggered separately from a background task or event, such as in the following `ForcecastUpdated` delegate, call <xref:Microsoft.AspNetCore.Components.ComponentBase.StateHasChanged%2A> to update the UI at the end of the background task or event:

0 commit comments

Comments
 (0)