MainGrid

The MainGrid component is a standalone grid for displaying Dataverse records. Unlike SubGrid, it does not require a parent RecordContext — it loads records directly from a specified table or view.

Loading by Table Name

Set the TableName parameter to automatically load all public views for that table. The first default view is selected initially.

<MainGrid TableName="contact" />

Loading by View IDs

Use ViewIds and DefaultViewId to control exactly which views are available and which one is selected on load. You can also provide CustomViewDefinitions with inline FetchXML to define views directly in code.

<MainGrid ViewIds="_viewIds"
          DefaultViewId="@(new Guid("..."))">
</MainGrid>

@code {
    private List<Guid> _viewIds = new List<Guid>
    {
        new Guid("..."),
        new Guid("..."),
    };
}

Custom Views with FetchXML

Use CustomViewDefinitions to define views with custom FetchXML queries. This is useful for views that include filters based on the current user, linked entities, or other dynamic criteria.

Note

The Id for a custom GridViewDefinition must be a unique random GUID that does not correspond to an existing Dataverse view. If it matches an existing view ID, the Dataverse view will take precedence and the custom definition will be ignored.

private List<GridViewDefinition> _customViews = new List<GridViewDefinition>
{
    new GridViewDefinition
    {
        Id = new Guid("..."),
        TableName = "contact",
        FetchXml = @"<fetch>
            <entity name='contact'>
                <attribute name='fullname' />
                <attribute name='emailaddress1' />
                <order attribute='fullname' />
            </entity>
        </fetch>",
        Columns = new List<ViewColumn>
        {
            new ViewColumn { ColumnName = "fullname", Width = 200 },
            new ViewColumn { ColumnName = "emailaddress1", Width = 250 },
        }
    }
};

Toolbar Buttons

The MainGrid supports the same toolbar buttons as SubGrid. For standalone grids, NavigateNewRecordGridButton and NavigateEditRecordGridButton are commonly used to navigate to separate form pages. See the Grid Buttons documentation for a complete reference of all available buttons and their configuration options.

<MainGrid TableName="contact">
    <Buttons>
        <NavigateNewRecordGridButton Url="/contacts/new" />
        <NavigateEditRecordGridButton Url="/contacts/edit?contactId={0}" />
    </Buttons>
</MainGrid>

Search Box Behavior

When the user types in the grid's search box, the configured view is automatically re-queried with additional filter conditions applied to every search-eligible column shown in the view. The conditions are joined with OR logic, so a record is included if any of its visible columns match the search term. The default match semantics differ depending on the column type.

Text and Lookup Columns

Text columns (string fields) and lookup columns (matched against the target record's primary name) use a starts with search by default. Typing joh matches values that begin with joh — for example John or Johnson. The match is delegated to FetchXML's like operator, which is case-insensitive in Dataverse.

Use * as a wildcard for more flexible matching. Typing *hn performs a contains-style match (e.g. John, Johnson); typing j*n matches values where any characters can appear between the j and the n (e.g. John, Joneson). The wildcard is converted to FetchXML's % wildcard at query time.

Numeric and Money Columns

Numeric columns — int, big int, decimal, double, and money — support comparison operators in the search term. The search box parses an optional leading operator and applies the corresponding FetchXML condition operator:

  • = 100 or just 100  —  equal (the default when no operator is specified)
  • > 100  —  greater than
  • < 100  —  less than
  • >= 100  —  greater than or equal
  • <= 100  —  less than or equal

Note

Search conditions for every column type are added to the same OR filter group, so the same search term is evaluated against text columns, lookup columns, and numeric columns simultaneously. Typing 100 in a grid that has both a name column and an amount column will match records whose name starts with 100 or whose amount equals 100. The search filter is layered on top of the view's existing filter, so view-level constraints (such as a statecode = 0 filter) are always preserved.

Disabling Search

Set AllowSearch="false" on the grid to hide the search box entirely. This is useful for grids that contain only a small fixed set of records, or where filtering is handled externally (for example via OnBeforeQuery or a custom toolbar).

<MainGrid TableName="contact" AllowSearch="false" />

Full Size Mode

Set FullSize="true" to make the grid expand to fill the full height of its parent container. This is useful when the grid is the main content of a page.

<PageLayout>
    <Body>
        <MainGrid TableName="contact" FullSize="true" />
    </Body>
</PageLayout>

Persisting the Selected View

Use SelectedViewQueryParameter to persist the currently selected view ID to a URL query parameter. This allows the selected view to be preserved when navigating back to the page.

<MainGrid TableName="contact"
          SelectedViewQueryParameter="viewId" />

Multi-Table Grids

A MainGrid can display views from different tables by including view IDs from multiple tables in the ViewIds collection. When the user switches views, the grid automatically loads the correct table's data. Use the OnClick callback on navigation buttons to dynamically set the URL based on the selected view's table name.

<MainGrid ViewIds="_viewIds"
          CustomViewDefinitions="_customViews"
          DefaultViewId="@(new Guid(AllContactsViewId))">
    <Buttons>
        <NavigateNewRecordGridButton OnClick="OnNewClick" />
        <NavigateEditRecordGridButton OnClick="OnEditClick" />
    </Buttons>
</MainGrid>

@code {
    private async Task OnNewClick(NavigateGridButtonContext ctx)
    {
        ctx.Url = ctx.GridContext.SelectedView.TableName switch
        {
            "contact" => "/contacts/new",
            "account" => "/accounts/new",
            _ => throw new Exception("Unknown table"),
        };
    }

    private async Task OnEditClick(NavigateGridButtonContext ctx)
    {
        ctx.Url = ctx.GridContext.SelectedView.TableName switch
        {
            "contact" => "/contacts/edit?id={0}",
            "account" => "/accounts/edit?id={0}",
            _ => throw new Exception("Unknown table"),
        };
    }
}

Filtering with OnBeforeQuery

Use the OnBeforeQuery parameter to apply additional filter criteria to the FetchXML query before it is executed. The callback receives a FetchXMLBuilder and must return it after applying any modifications. This is called after all built-in search, sort, and paging logic has been applied.

<MainGrid TableName="contact"
          OnBeforeQuery="ApplyContactFilter" />

@code {
    private Task<FetchXMLBuilder> ApplyContactFilter(FetchXMLBuilder fetchXmlBuilder)
    {
        var filter = fetchXmlBuilder.Fetch.Entity.AddFilter();
        var condition = filter.AddCondition();
        condition.Column = "statecode";
        condition.Operator = ConditionOperator.Equal;
        condition.Value = "0";

        return Task.FromResult(fetchXmlBuilder);
    }
}

Tip

The OnBeforeQuery callback is ideal for applying context-specific filters such as restricting records to a specific status, the current user, or a parent record. Because filters are applied at the query level, filtered-out records are never retrieved from Dataverse.

MainGrid Class

Parameters

Name
Type
Default
Description
AllowChangingItemsPerPagebool
True
When true, the user can change the number of items displayed per page.
AllowEditbool
False
Should the option be available for the user to turn on inline editing for the grid.
AllowEditOnRowDoubleClickbool
True
If a button is present that has the set to true,
and this is set to 'true', then the event delegate will be called for the record.
AllowSearchbool
True
Should the user be allowed to search the grid.
BorderVisiblebool
True
Controls whether a visible border is rendered around the grid.
ButtonsRenderFragment?
Optional render fragment used to define the button toolbar displayed above the grid.
CustomViewDefinitionsList<GridViewDefinition>?
Custom views to display in the dropdown.
DefaultItemsPerPageint
50
Default number of records to load on a page.
DefaultViewIdGuid?
Id of the view that the grid should display upon initial load.
Editablebool
False
Is inline editing turned on for the grid.
FullSizebool
False
When true, the grid expands to fill all available vertical space instead of using a fixed minimum height.
HidePagingbool
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.
IsDirtybool
False
Indicates whether the grid has unsaved create, update, or delete operations pending.
MaxHeightstring?
Max Height that the grid control should expand to.
MinHeightstring?
250px
Minimum height that the grid control should occupy.
ModeGridMode
RecordSelection
Sets the behavioural mode of the grid, such as default interaction or record-selection mode.
OnBeforeQueryFunc<FetchXMLBuilder, Task<FetchXMLBuilder>>?
Optional callback to apply additional filter criteria to the FetchXML query before it is executed.
PageSizesIEnumerable<int>
Collection of available page sizes for the grid.
PagingModeGridPagingMode
Paged
Determines whether the grid uses traditional paging or infinite-scroll virtualisation.
SelectedRecordsIEnumerable<TableRecord>
Records that are currently selected in the Grid.
SelectedViewQueryParameterstring?
Query parameter to persist the selected view to.
SelectFromEntireRowbool
True
When true, clicking anywhere on a row selects it; when false, only the checkbox selects the row.
SelectModeDataGridSelectMode
Multiple
Controls whether the grid allows single or multiple row selection.
TableNamestring?
The logical name of the table whose public views should be loaded. Only applicable when no values are specified for or .
Titlestring?
Name to display when the view dropdown is not displayed.
ViewIdsIEnumerable<Guid>?
List of id's of the views that the grid should limit to in the view dropdown.
ViewSortViewSort
NameAscending
Sort order of the views in the view dropdown.
Name: AllowChangingItemsPerPage
Type: bool
Default: True
Description: When true, the user can change the number of items displayed per page.
Name: AllowEdit
Type: bool
Default: False
Description: Should the option be available for the user to turn on inline editing for the grid.
Name: AllowEditOnRowDoubleClick
Type: bool
Default: True
Description: If a button is present that has the set to true,
and this is set to 'true', then the event delegate will be called for the record.
Name: AllowSearch
Type: bool
Default: True
Description: Should the user be allowed to search the grid.
Name: BorderVisible
Type: bool
Default: True
Description: Controls whether a visible border is rendered around the grid.
Name: Buttons
Type: RenderFragment?
Description: Optional render fragment used to define the button toolbar displayed above the grid.
Name: CustomViewDefinitions
Type: List<GridViewDefinition>?
Description: Custom views to display in the dropdown.
Name: DefaultItemsPerPage
Type: int
Default: 50
Description: Default number of records to load on a page.
Name: DefaultViewId
Type: Guid?
Description: Id of the view that the grid should display upon initial load.
Name: Editable
Type: bool
Default: False
Description: Is inline editing turned on for the grid.
Name: FullSize
Type: bool
Default: False
Description: When true, the grid expands to fill all available vertical space instead of using a fixed minimum height.
Name: HidePaging
Type: bool
Default: False
Description: 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.
Name: IsDirty
Type: bool
Default: False
Description: Indicates whether the grid has unsaved create, update, or delete operations pending.
Name: MaxHeight
Type: string?
Description: Max Height that the grid control should expand to.
Name: MinHeight
Type: string?
Default: 250px
Description: Minimum height that the grid control should occupy.
Name: Mode
Type: GridMode
Default: RecordSelection
Description: Sets the behavioural mode of the grid, such as default interaction or record-selection mode.
Name: OnBeforeQuery
Type: Func<FetchXMLBuilder, Task<FetchXMLBuilder>>?
Description: Optional callback to apply additional filter criteria to the FetchXML query before it is executed.
Name: PageSizes
Type: IEnumerable<int>
Description: Collection of available page sizes for the grid.
Name: PagingMode
Type: GridPagingMode
Default: Paged
Description: Determines whether the grid uses traditional paging or infinite-scroll virtualisation.
Name: SelectedRecords
Type: IEnumerable<TableRecord>
Description: Records that are currently selected in the Grid.
Name: SelectedViewQueryParameter
Type: string?
Description: Query parameter to persist the selected view to.
Name: SelectFromEntireRow
Type: bool
Default: True
Description: When true, clicking anywhere on a row selects it; when false, only the checkbox selects the row.
Name: SelectMode
Type: DataGridSelectMode
Default: Multiple
Description: Controls whether the grid allows single or multiple row selection.
Name: TableName
Type: string?
Description: The logical name of the table whose public views should be loaded. Only applicable when no values are specified for or .
Name: Title
Type: string?
Description: Name to display when the view dropdown is not displayed.
Name: ViewIds
Type: IEnumerable<Guid>?
Description: List of id's of the views that the grid should limit to in the view dropdown.
Name: ViewSort
Type: ViewSort
Default: NameAscending
Description: Sort order of the views in the view dropdown.

Events

Name
Type
Description
EditableChangedEventCallback<bool>
Callback invoked when the inline editing state changes.
SelectedRecordsChangedEventCallback<IEnumerable<TableRecord>>
Callback invoked when the selected records collection changes.
Name: EditableChanged
Type: EventCallback<bool>
Description: Callback invoked when the inline editing state changes.
Name: SelectedRecordsChanged
Type: EventCallback<IEnumerable<TableRecord>>
Description: Callback invoked when the selected records collection changes.

Methods

Name
Parameters
Type
Description
ClearSelectionAsyncTask
Clears all currently selected rows.
RefreshAsyncbool forceRefresh
Task
Instructs the grid to re-fetch and render the current data from the supplied data source.
Validatebool
Validates all editable rows in the grid.
Name: ClearSelectionAsync
Type: Task
Description: Clears all currently selected rows.
Name: RefreshAsync
Parameters: bool forceRefresh
Type: Task
Description: Instructs the grid to re-fetch and render the current data from the supplied data source.
Name: Validate
Type: bool
Description: Validates all editable rows in the grid.