terminalCode Example
VirtualGrid — efficiently rendering large scrollable lists in s&box UI
VirtualGrid — Efficiently Rendering Large Lists in UI
VirtualGrid is a s&box UI panel that virtualizes a large collection — only the visible cells are created in the DOM. Scrolling destroys off-screen cells and creates new ones, keeping memory and layout cost constant regardless of list size.Basic Usage in Razor
RAZOR
@using Sandbox;
@using Sandbox.UI;
@inherits PanelComponent
<root>
<VirtualGrid Items=@Items ItemSize=@(new Vector2(120, 120))>
<Item Context="item">
@if ( item is PackageEntry entry )
{
<div class="package-card">
<label>@entry.Title</label>
</div>
}
</Item>
</VirtualGrid>
</root>
@code {
public IEnumerable<PackageEntry> Items { get; set; } = Array.Empty<PackageEntry>();
protected override int BuildHash() => System.HashCode.Combine( Items );
}ItemSize
ItemSize is a Vector2. The grid scales cells up so they fit flush in the container while preserving the aspect ratio:RAZOR
<VirtualGrid Items=@Items ItemSize=@(new Vector2(200, 150))>Spacing Between Cells
Use CSS gap on the VirtualGrid element:
CSS
.my-grid VirtualGrid {
gap: 8px;
}Required: Give VirtualGrid a Size
VirtualGrid must have an explicit size in CSS — it won't size itself:CSS
.my-grid VirtualGrid {
width: 100%;
height: 100%;
}Updating the List
Assign a new collection to Items and call StateHasChanged() to trigger a rebuild:
CSHARP
protected override void OnUpdate()
{
var newItems = GetFilteredPackages();
if ( newItems != Items )
{
Items = newItems;
StateHasChanged();
}
}When to Use
- Package browsers, item shops, inventory grids with hundreds of entries
- Any scrollable list where creating all DOM nodes at once would be slow
- All items must be the same size — VirtualGrid doesn't support variable-height rows
Was this helpful?