Are you sure you'd like to delete the 0 record/s?
Page size
Full Name | Mobile Phone | Email | Company Name | Age | |
|---|---|---|---|---|---|
| No records found. |
The SubGrid component displays Dataverse records related to a parent record via a specified relationship. It must be placed inside a RecordContext and requires a RelationshipName parameter that specifies which relationship to use.
SubGrid supports both one-to-many (1:N) and many-to-many (N:N) relationships. The component automatically detects the relationship type and adjusts its behavior accordingly.
NewRecordGridButton, EditRecordGridButton, and DeleteRecordGridButton are used to create, edit, and delete related records.LinkExistingRecordGridButton and UnlinkExistingRecordGridButton are used to associate and disassociate records. Create and delete operations are automatically converted to associate and disassociate requests.Use ViewIds to specify which views are available in the view selector dropdown, and DefaultViewId to set the initially selected view. If neither is provided, the grid automatically loads all public views for the related table. You can also provide CustomViewDefinitions with inline FetchXML to define views directly in code.
<SubGrid RelationshipName="contact_customer_accounts"
ViewIds="_contactViews"
DefaultViewId="@(new Guid("..."))">
</SubGrid>
@code {
private List<Guid> _contactViews = new List<Guid>
{
new Guid("..."),
new Guid("..."),
};
}
Add buttons to the grid toolbar using the Buttons render fragment. See the Grid Buttons documentation for detailed configuration options including dialog positioning, wizard forms, and save behavior. The following built-in buttons are available:
NewRecordGridButton — Opens a dialog form to create a new related record (1:N)EditRecordGridButton — Opens a dialog form to edit the selected recordDeleteRecordGridButton — Deletes selected recordsLinkExistingRecordGridButton — Associates an existing record via a N:N relationshipUnlinkExistingRecordGridButton — Disassociates selected records from a N:N relationshipNavigateNewRecordGridButton — Navigates to a URL to create a new recordNavigateEditRecordGridButton — Navigates to a URL to edit the selected record<!-- 1:N relationship buttons -->
<SubGrid RelationshipName="contact_customer_accounts">
<Buttons>
<NewRecordGridButton TForm="NewContactForm" />
<EditRecordGridButton TForm="EditContactForm" />
<DeleteRecordGridButton />
</Buttons>
</SubGrid>
<!-- N:N relationship buttons -->
<SubGrid RelationshipName="ppp_Account_ppp_Region_ppp_Region">
<Buttons>
<LinkExistingRecordGridButton />
<UnlinkExistingRecordGridButton />
</Buttons>
</SubGrid>
Set AllowEdit="true" to enable a settings toggle that lets users switch to inline editing mode. When enabled, editable columns render as form controls directly in the grid. Inline editing is only supported for 1:N relationships.
<SubGrid RelationshipName="contact_customer_accounts"
AllowEdit="true">
<Buttons>
<NewRecordGridButton TForm="NewContactForm" />
<EditRecordGridButton TForm="EditContactForm" />
</Buttons>
</SubGrid>
The grid supports paged navigation with configurable page sizes via DefaultItemsPerPage and PageSizes. Search is enabled by default and can be disabled with AllowSearch="false".
<SubGrid RelationshipName="contact_customer_accounts"
DefaultItemsPerPage="10"
PageSizes="@(new[] { 10, 25, 50 })"
AllowSearch="false">
</SubGrid>
Here is an example that demonstrates the use of a SubGrid component for a 1:N relationship. The grids below are linked to an 'Account' record.
Are you sure you'd like to delete the 0 record/s?
Page size
Full Name | Mobile Phone | Email | Company Name | Age | |
|---|---|---|---|---|---|
| No records found. |
Here is an example that demonstrates the use of a SubGrid component for a N:N relationship.
Are you sure you'd like to unlink the 0 record/s?
Page size
Name | |
|---|---|
| No records found. |
Name | Type | Default | Description |
|---|---|---|---|
AllowChangingItemsPerPage | bool | True | When |
AllowDownloadForFileColumns | bool | True | When |
AllowEdit | bool | False | Should the option be available for the user to turn on inline editing for the grid. |
AllowNavigateOnPrimaryNameClick | bool | True | When GridButton with |
AllowNavigateOnRowDoubleClick | bool | True | When GridButton with GridButton.OnClick for the row's record — opening the edit dialog or navigating to the edit URL, whichever the button does. Set to |
AllowPreviewForFileColumns | bool | True | When |
AllowSearch | bool | True | Should the user be allowed to search the grid. |
BorderVisible | bool | True | Controls whether a visible border is rendered around the grid. |
Buttons | RenderFragment? | Optional render fragment used to define the button toolbar displayed above the grid. | |
CustomViewDefinitions | List<GridViewDefinition>? | Custom views to display in the dropdown. | |
DefaultItemsPerPage | int | 50 | Default number of records to load on a page. |
DefaultViewId | Guid? | Id of the view that the grid should display upon initial load. | |
Editable | bool | False | Is inline editing turned on for the grid. |
FullSize | bool | False | When |
HidePaging | bool | False | Force the page size and paging components to be hidden. Only do this when the number of items is known and the page size is set to something greater than the item count. |
IsDirty | bool | False | Indicates whether the grid has unsaved create, update, or delete operations pending. |
LoadedRecords | IEnumerable<TableRecord> | Records currently rendered in the grid (the most recent page of results). Intended for toolbar commands that need to act on 'everything shown' — e.g. a bulk download button. Does not span pages; bulk-across-pages operations should run their own unpaged fetch instead. | |
MaxHeight | string? | Max Height that the grid control should expand to. | |
MinHeight | string? | 250px | Minimum height that the grid control should occupy. |
Mode | GridMode | RecordSelection | Sets the behavioural mode of the grid, such as default interaction or record-selection mode. |
OnBeforeQuery | Func<FetchXMLBuilder, Task<FetchXMLBuilder>>? | Optional callback to apply additional filter criteria to the FetchXML query before it is executed. | |
PageSizes | IEnumerable<int> | Collection of available page sizes for the grid. | |
PagingMode | GridPagingMode | Paged | Determines whether the grid uses traditional paging or infinite-scroll virtualisation. |
PersistedRowsSnapshot | PersistedGridState? | Server-prerender → interactive handoff for the rendered page of rows. The framework auto-persists this property at the end of prerender and re-hydrates it before GridBase.OnInitializedAsync on the interactive side, so the data fetch can be skipped on first interactive render. Keyed by render-tree position by the framework; the PersistedGridState.ViewId field is checked at consumption time so a rerender against a different view discards the stale rows. Public per the framework's requirement — | |
Record | TableRecord? | The parent record supplied via a cascading parameter; related records are filtered by this record's identity. | |
RelationshipName | string | The schema name of the relationship used to filter and display related records in this sub-grid. | |
SelectedRecords | IEnumerable<TableRecord> | Records that are currently selected in the Grid. | |
SelectedViewQueryParameter | string? | Query parameter to persist the selected view to. | |
SelectFromEntireRow | bool | True | When |
SelectMode | DataGridSelectMode | Multiple | Controls whether the grid allows single or multiple row selection. |
Title | string? | Name to display when the view dropdown is not displayed. | |
TransformViewAsync | Func<GridViewDefinition, Task<GridViewDefinition>>? | Optional callback that runs immediately after a view is loaded and before the grid uses it to build columns or queries. Return a modified Models.GridViewDefinition to transform what the grid ultimately renders — for example, to ensure a specific column is always present regardless of the view's own configuration. Async so callers can consult metadata caches, services, or other async resources while deciding what to include. | |
ViewIds | IEnumerable<Guid>? | List of id's of the views that the grid should limit to in the view dropdown. | |
ViewSort | ViewSort | NameAscending | Sort order of the views in the view dropdown. |
AllowChangingItemsPerPageAllowDownloadForFileColumnsAllowEditAllowNavigateOnPrimaryNameClickGridButton with AllowNavigateOnRowDoubleClickGridButton with GridButton.OnClick for the row's record — opening the edit dialog or navigating to the edit URL, whichever the button does. Set to AllowPreviewForFileColumnsAllowSearchBorderVisibleButtonsCustomViewDefinitionsDefaultItemsPerPageDefaultViewIdEditableFullSizeHidePagingIsDirtyLoadedRecordsMaxHeightMinHeightModeOnBeforeQueryPageSizesPagingModePersistedRowsSnapshotGridBase.OnInitializedAsync on the interactive side, so the data fetch can be skipped on first interactive render. Keyed by render-tree position by the framework; the PersistedGridState.ViewId field is checked at consumption time so a rerender against a different view discards the stale rows. Public per the framework's requirement — RecordRelationshipNameSelectedRecordsSelectedViewQueryParameterSelectFromEntireRowSelectModeTitleTransformViewAsyncModels.GridViewDefinition to transform what the grid ultimately renders — for example, to ensure a specific column is always present regardless of the view's own configuration. Async so callers can consult metadata caches, services, or other async resources while deciding what to include.ViewIdsViewSortName | Type | Description |
|---|---|---|
EditableChanged | EventCallback<bool> | Callback invoked when the inline editing state changes. |
SelectedRecordsChanged | EventCallback<IEnumerable<TableRecord>> | Callback invoked when the selected records collection changes. |
EditableChangedSelectedRecordsChangedName | Parameters | Type | Description |
|---|---|---|---|
ClearSelectionAsync | Task | Clears all currently selected rows. | |
OpenFileDownloadAsync | TableRecord record string columnName | Task | Fetches the file/image column's bytes for record and streams them to the user's browser as a download. Invoked by the per-row download icon in file and image cells. |
OpenFilePreviewAsync | TableRecord record string columnName | Task | Opens the inline preview dialog for the file/image column columnName on record. Invoked by the per-row preview icon in file/image cells and also available to composing components (for example, a toolbar button on a wrapping grid) that want a programmatic entry point. |
RefreshAsync | bool forceRefresh | Task | Instructs the grid to re-fetch and render the current data from the supplied data source. |
Validate | bool | Validates all editable rows in the grid. |
ClearSelectionAsyncOpenFileDownloadAsyncrecord and streams them to the user's browser as a download. Invoked by the per-row download icon in file and image cells.OpenFilePreviewAsynccolumnName on record. Invoked by the per-row preview icon in file/image cells and also available to composing components (for example, a toolbar button on a wrapping grid) that want a programmatic entry point.RefreshAsyncValidateApply begins with filter on the following columns:
Apply begins with filter on the following columns:
Apply begins with filter on the following columns:
Apply begins with filter on the following columns: