MgGrid System
Comprehensive documentation for the MgGrid component family — the primary UI data grid pattern in the AyCode.Blazor framework.
Source: Components/Grids/
For SignalR transport: AyCode.Services/docs/SIGNALR/README.md (in AyCode.Core repo)
For AcSignalRDataSource: AyCode.Services/docs/SIGNALR_DATASOURCE/README.md (in AyCode.Core repo)
Overview
MgGridBase is an abstract generic Blazor component that extends DevExpress DxGrid with:
- Automatic SignalR CRUD via
AcSignalRDataSource (see AyCode.Core docs)
- Layout persistence — column order, widths, sorting, grouping auto-saved to
localStorage
- Master-detail hierarchy — nested grids share context via
CascadingParameter
- InfoPanel integration — side panel shows focused row details, supports edit mode
- Fullscreen mode — standalone overlay or via
MgGridWithInfoPanel wrapper
- Change tracking — client-side tracking with server sync via
SaveChangesAsync
- Filter panel —
FilterPanel slot below the toolbar hosting MgGridFilterPanelTagBox components (IMgGridFilterPanelComponent); per-field criteria AND-combined by DevExpress with the user's filter row; toolbar Show/Hide toggle + built-in right-aligned Clear button (see MGGRID_PARAMETERS.md → Filter Panel; design: AyCode.Core repo docs/adr/0004-signalr-datasource-server-side-filtering.md)
Detailed Documentation
| File |
Topics |
MGGRID_PARAMETERS.md |
Component parameters (required, CRUD tags, data & context, display), quick-filter panel (FilterPanel slot + MgTagBox), event callbacks, default grid settings |
MGGRID_CRUD.md |
Lifecycle, CRUD operations, ID generation, edit flow, disposal |
MGGRID_LAYOUT.md |
Layout persistence (storage keys, three tiers, operations, persisted state) |
MGGRID_DETAIL.md |
Master-detail hierarchy |
MGGRID_RENDERING.md |
Fullscreen mode, rendering |
MGGRID_INFOPANEL.md |
MgGridInfoPanel, MgGridWithInfoPanel wrapper, responsive layout, templates, editors |
MGGRID_TOOLBAR.md |
MgGridToolbarBase, MgGridToolbarTemplate (buttons, parameters, state) |
MGGRID_COLUMNS.md |
MgGridDataColumn (InfoPanel params, UrlLink) |
MGGRID_DATASOURCE.md |
MgGridSignalRDataSource (server-side data, local cache, background refresh) |
MGGRID_ISSUES.md |
Known issues (ACBLAZOR-GRID-I-*, ACBLAZOR-GRID-B-*) |
MGGRID_TODO.md |
Planned work (ACBLAZOR-GRID-T-*) — refactors, missing features, optimizations |
Component Hierarchy
DxGrid (DevExpress)
└── MgGridBase<TSignalRDataSource, TDataItem, TId, TLoggerClient> (AyCode.Blazor — abstract)
└── [Project-specific adapter] ← consumer fixes TSignalRDataSource, TId, TLoggerClient
└── [Concrete entity grid] ← consumer sets CRUD tags in constructor
Companion components (wrapper, toolbars, column, InfoPanel, data source) are named in the table above; per-file source summaries: Components/Grids/README.md.
Generic Type Parameters
MgGridBase<TSignalRDataSource, TDataItem, TId, TLoggerClient>
| Parameter |
Constraint |
Purpose |
TSignalRDataSource |
: AcSignalRDataSource<…> |
SignalR-backed data source (see AyCode.Services/docs/SIGNALR_DATASOURCE/README.md in AyCode.Core repo) |
TDataItem |
: class, IId<TId> |
Entity type displayed in the grid |
TId |
: struct |
Primary key type (int, Guid) |
TLoggerClient |
: AcLoggerBase |
Logger for diagnostics |
Usage Example (Project-Specific Adapter)
// Project adapter — fixes TSignalRDataSource, TId, TLoggerClient for the entire project
public class MyProjectGridBase<TDataItem>
: MgGridBase<MySignalRDataSource<TDataItem>, TDataItem, int, MyLoggerClient>
where TDataItem : class, IId<int>
{
[Inject] public required MyLoggedInModel LoggedInModel { get; set; }
protected override int GetLayoutUserId() => LoggedInModel.UserId;
}
// Concrete grid — only TDataItem remains open
public class GridOrderBase : MyProjectGridBase<Order>
{
public GridOrderBase()
{
GetAllMessageTag = MySignalRTags.GetOrders;
AddMessageTag = MySignalRTags.AddOrder;
UpdateMessageTag = MySignalRTags.UpdateOrder;
}
}
Interface: IMgGridBase
The public contract exposed to companion components (toolbar, InfoPanel, wrapper):
| Member |
Type |
Description |
IsSyncing |
bool |
Whether SignalR sync is in progress |
Caption |
string |
Grid title |
GridEditState |
MgGridEditState |
None / New / Edit |
ParentGrid |
IMgGridBase? |
Parent in master-detail hierarchy |
GetRootGrid() |
IMgGridBase |
Walks to topmost grid |
StepPrevRow() |
void |
Navigate to previous visible row |
StepNextRow() |
void |
Navigate to next visible row |
InfoPanelInstance |
IInfoPanelBase? |
Resolved InfoPanel reference |
IsFullscreen |
bool |
Current fullscreen state |
AutomaticLayoutStorageKey |
string |
Current auto-save storage key |
ToggleFullscreen() |
void |
Toggle fullscreen mode |
SetFilterPanelCriteria(fieldName, criteria) |
void |
Apply/clear a filter-panel per-field criteria (delegates to DevExpress SetFieldFilterCriteria; null clears the field; the per-field slot is shared with the filter row) |
HasFilterPanel |
bool |
Whether the grid has a FilterPanel (drives toolbar-toggle visibility) |
IsFilterPanelVisible |
bool |
Current quick-filter panel visibility |
ToggleFilterPanel() |
void |
Show/hide the quick-filter panel |
GridSizeMode |
SizeMode? |
The grid's DevExpress SizeMode; filter-panel components inherit it as their default when the consumer sets none |
GetFilterPanelCriteria(fieldName) |
CriteriaOperator? |
Reads back a field's criteria (counterpart of SetFilterPanelCriteria; used to restore components after a persisted layout applied) |
RegisterFilterPanelComponent(component) |
void |
Registers an IMgGridFilterPanelComponent for criteria reconcile (weakly held, synced immediately; hidden panel ⇒ the components' OWN criteria are cleared) |
ClearFilterPanel() |
void |
Clears every registered component's OWN criteria + empties the components (filter row untouched); wired to the panel's built-in Clear button (enabled only while a panel-owned criteria is active) |
RefreshFilterPanel() |
void |
Re-runs the filter-panel reconcile on demand — call after a late/in-place lookup-data load (e.g. AcObservableCollection.Replace) so restored selections resolve against the arrived data |
SaveUserLayoutAsync() |
Task |
Save layout manually |
LoadUserLayoutAsync() |
Task |
Load manually saved layout |
ResetLayoutAsync() |
Task |
Reset to default layout |
HasUserLayoutAsync() |
Task<bool> |
Check if manual save exists (optimistic true when server layouts are enabled) |
Event Args Classes
| Class |
Base |
Extra Properties |
GridDataItemChangedEventArgs<T> |
— |
Grid, DataItem, TrackingState, CancelStateChangeInvoke |
GridDataItemChangingEventArgs<T> |
GridDataItemChangedEventArgs<T> |
IsCanceled |