Component

BOBDataGrid

Strongly-typed tabular data with sorting, filtering, pagination, selection, custom templates, and more — declaratively.

API reference ↗

Basic usage

Bind Items and declare BOBDataColumn elements inside Columns.

5 rows.
IDNameEmailAge
1Alice Johnson[email protected]29
2Marcus Chen[email protected]34
3Priya Patel[email protected]41
4Diego Martinez[email protected]26
5Hana Nakamura[email protected]38
RAZOR
<BOBDataGrid Items="_people">
    <Columns>
        <BOBDataColumn TItem="Person" Property="@(p => p.Id)" Header="ID" />
        <BOBDataColumn TItem="Person" Property="@(p => p.Name)" Header="Name" />
        <BOBDataColumn TItem="Person" Property="@(p => p.Email)" Header="Email" />
        <BOBDataColumn TItem="Person" Property="@(p => p.Age)" Header="Age" />
    </Columns>
</BOBDataGrid>

Sortable

Enable Sortable on the grid and on the columns you want clickable.

5 rows.
Email
1Alice Johnson[email protected]29
2Marcus Chen[email protected]34
3Priya Patel[email protected]41
4Diego Martinez[email protected]26
5Hana Nakamura[email protected]38
RAZOR
<BOBDataGrid Items="_people" Sortable="true">
    <Columns>
        <BOBDataColumn TItem="Person" Property="@(p => p.Id)" Header="ID" Sortable="true" />
        <BOBDataColumn TItem="Person" Property="@(p => p.Name)" Header="Name" Sortable="true" />
        <BOBDataColumn TItem="Person" Property="@(p => p.Email)" Header="Email" />
        <BOBDataColumn TItem="Person" Property="@(p => p.Age)" Header="Age" Sortable="true" />
    </Columns>
</BOBDataGrid>

Filter + pagination

35 rows. Page 1 of 4.
IDNameEmailAge
1Person 01[email protected]21
2Person 02[email protected]22
3Person 03[email protected]23
4Person 04[email protected]24
5Person 05[email protected]25
6Person 06[email protected]26
7Person 07[email protected]27
8Person 08[email protected]28
9Person 09[email protected]29
10Person 10[email protected]30
Showing 1 to 10 of 35
RAZOR
<BOBDataGrid Items="_big"
             Filterable="true"
             FilterPlaceholder="Search..."
             PageSize="10"
             ShowPageSizeSelector="true"
             PageSizeOptions="@(new[] { 5, 10, 25 })">
    <Columns>
        <BOBDataColumn TItem="Person" Property="@(p => p.Id)" Header="ID" Filterable="true" />
        <BOBDataColumn TItem="Person" Property="@(p => p.Name)" Header="Name" Filterable="true" />
        <BOBDataColumn TItem="Person" Property="@(p => p.Email)" Header="Email" Filterable="true" />
        <BOBDataColumn TItem="Person" Property="@(p => p.Age)" Header="Age" Filterable="true" />
    </Columns>
</BOBDataGrid>

Multiple selection

5 rows.
NameEmailAge
Alice Johnson[email protected]29
Marcus Chen[email protected]34
Priya Patel[email protected]41
Diego Martinez[email protected]26
Hana Nakamura[email protected]38
RAZOR
<BOBDataGrid TItem="Person"
             Items="_people"
             SelectionMode="SelectionMode.Multiple"
             SelectedItems="_selected"
             SelectedItemsChanged="@(s => { _selected = s; StateHasChanged(); })">
    <Columns>
        <BOBDataColumn TItem="Person" Property="@(p => p.Name)" Header="Name" />
        <BOBDataColumn TItem="Person" Property="@(p => p.Email)" Header="Email" />
        <BOBDataColumn TItem="Person" Property="@(p => p.Age)" Header="Age" />
    </Columns>
</BOBDataGrid>

Custom templates

Use Template with context to render any markup inside a cell.

5 rows.
PersonAge
Alice Johnson 29
Marcus Chen 34
Priya Patel 41
Diego Martinez 26
Hana Nakamura 38
RAZOR
<BOBDataGrid Items="_people">
    <Columns>
        <BOBDataColumn TItem="Person" Header="Person">
            <Template>
                <strong>@context.Name</strong>
                <div style="font-size: 0.85em; opacity: 0.7;">@context.Email</div>
            </Template>
        </BOBDataColumn>
        <BOBDataColumn TItem="Person" Property="@(p => p.Age)" Header="Age" Align="ColumnAlign.Right" />
    </Columns>
</BOBDataGrid>

Alignment & width

5 rows.
Name (left)Email (center)Age (right)
Alice Johnson[email protected]29
Marcus Chen[email protected]34
Priya Patel[email protected]41
Diego Martinez[email protected]26
Hana Nakamura[email protected]38
RAZOR
<BOBDataGrid Items="_people">
    <Columns>
        <BOBDataColumn TItem="Person" Property="@(p => p.Name)" Header="Name (left)" Align="ColumnAlign.Left" Width="200px" />
        <BOBDataColumn TItem="Person" Property="@(p => p.Email)" Header="Email (center)" Align="ColumnAlign.Center" />
        <BOBDataColumn TItem="Person" Property="@(p => p.Age)" Header="Age (right)" Align="ColumnAlign.Right" Width="80px" />
    </Columns>
</BOBDataGrid>

Shadow & Border

5 rows.
NameAge
Alice Johnson29
Marcus Chen34
Priya Patel41
Diego Martinez26
Hana Nakamura38
5 rows.
NameAge
Alice Johnson29
Marcus Chen34
Priya Patel41
Diego Martinez26
Hana Nakamura38
RAZOR
<BOBDataGrid Items="_people" Shadow="@BOBShadowPresets.Elevation(3)">
    <Columns>
        <BOBDataColumn TItem="Person" Property="@(p => p.Name)" Header="Name" />
        <BOBDataColumn TItem="Person" Property="@(p => p.Age)" Header="Age" />
    </Columns>
</BOBDataGrid>
<BOBDataGrid Items="_people" Border="@BOBBorderPresets.RoundedLarge">
    <Columns>
        <BOBDataColumn TItem="Person" Property="@(p => p.Name)" Header="Name" />
        <BOBDataColumn TItem="Person" Property="@(p => p.Age)" Header="Age" />
    </Columns>
</BOBDataGrid>

Properties

37 rows.
PropertyTypeDefaultDescription
FixedHeaderboolWhen , the header row stays fixed while scrolling.
RowTemplateRenderFragment<TItem>?Custom template for rendering each data row.
FooterTemplateRenderFragment?Custom template rendered inside the table footer.
CellBorderBorderStyle?Border style applied to individual cells.
RowBorderBorderStyle?Border style applied to rows.
ColumnsRenderFragment?Column definitions rendered inside the data collection.
ItemsIEnumerable<TItem>?Data items to display.
DensityBOBDensityBOBDensity.StandardVertical density (gap) of rows.
SizeBOBSizeBOBSize.MediumVisual size of the data collection.
HoverableBooleantrueWhen true (default), rows highlight on hover.
ShadowShadowStyle?Shadow style applied to the container.
SelectionModeSelectionModeSelectionMode.NoneRow selection mode.
SelectedItemsHashSet<TItem>?Currently selected items. Use with two-way binding.
SelectedItemsChangedEventCallback<HashSet<TItem>>Raised when the selection changes.
SortableBooleanWhen true, column headers are clickable for sorting.
DefaultSortColumnString?Name of the column to sort by on initial render.
DefaultSortDirectionSortDirection?Initial sort direction. Defaults to Ascending.
FilterableBooleanWhen true, a search box filters the displayed items.
FilterPlaceholderString"Search..."Placeholder text for the filter search box.
CustomFilterFunc<TItem, String, Boolean>?Custom predicate used to filter items. Receives the item and the search text.
PageSizeInt32?Number of items per page. When null, pagination is disabled.
PageSizeOptionsInt32[][10, 20, 50, 100]Available page sizes shown in the page-size selector.
ShowPageSizeSelectorBooleanWhen true, a dropdown lets the user change the page size.
EnableVirtualizationBooleanWhen true, only visible rows are rendered (improves performance for large lists).
HeightString?Fixed height of the container. Required for virtualization and fixed header.
EmptyContentRenderFragment?Custom template rendered when there are no items to display.
LoadingContentRenderFragment?Custom template rendered while Loading is true.
LoadingBooleanWhen true, the loading template is shown.
BorderBorderStyle?Border style applied to the container.
BackgroundColorString?Background color of the container. Accepts any valid CSS color value.
ItemPatternRowStylePattern?Alternating row style pattern (e.g. zebra striping).
OnRowClickEventCallback<TItem>Raised when a row is clicked and SelectionMode is not active.
OnSortEventCallback<DataCollectionSortEventArgs>Raised when the sort column or direction changes.
OnFilterEventCallback<DataCollectionFilterEventArgs>Raised when the filter text changes.
OnPageChangeEventCallback<DataCollectionPageChangeEventArgs>Raised when the current page changes.
VariantTVariant?
AdditionalAttributesIReadOnlyDictionary<String, Object>?