GridView
Grid tabular sortable / filterable / inline edit. Workhorse của Core. Cấu hình cột qua bảng `GridPolicy`.
Source:
Core/Components/GridView.csComponentTypetrong DB:GridView. KhiGroupByfield set, Core tự pickGroupGridView. Khi cần data lớn (>1000 row) dùngVirtualGridthay thế.
Cấu hình
ComType: GridView
Reference: Customer
DataSourceFilter: ?$filter=Active eq true&$top=200 # bắt buộc đủ "?$filter="
CanAdd: true
CanSearch: true
Editable: false
Field DB dùng
Bao gồm tất cả của ListView, plus:
| Field | Vai trò |
|---|---|
Editable | True → enable inline edit (empty row dưới cùng để insert). |
CanAdd | True → hiện nút “Thêm dòng” trong grid. |
ClassName | Class CSS thêm cho grid container. |
FormatData | Format hiển thị cell (chỉ áp khi grid render thay vì cell renderer). |
FocusSearch | True → auto focus search box khi grid render. |
IsSumary | True → render dòng summary (footer) tổng hợp. |
IsCollapsible | True → group rows có thể thu/mở. |
OrderBySumary | Field sắp xếp summary (nếu có nhiều aggregate). |
FormatSumaryField | Format string cho cell summary. |
GroupBy | Field group rows theo (cho GroupGridView thừa kế). |
GroupFormat | Format header group ("{StatusName} ({COUNT})"). |
AddDate | True → auto thêm filter ngày hôm nay khi load. |
DefaultAddStart | Số tháng/ngày offset đầu range (vd -7 = 7 ngày trước). |
DefaultAddEnd | Số tháng/ngày offset cuối range. |
DefaultVal | Giá trị mặc định cho cell mới. |
RefClass | Class CSS cho reference display. |
CastProp | Hint casting property cho Bridge.NET. |
PopulateField | Auto populate field từ reference khi pick row. |
PostOrder | Order sau khi render xong. |
PreQuery | Query chạy trước khi load data chính (lookup dependency). |
ShowAudit | True → hiện audit info (created/updated by). |
ShowNull | True → hiển thị null cell rõ ràng (thay vì empty). |
Events kích hoạt
Kế thừa từ ListView, thêm:
| Event | Method signature |
|---|---|
change | (rowData, rowSection) |
BeforeCreated | (rowData, this) |
AfterCreated | (rowData) |
AfterEmptyRowCreated | (emptyRow) — empty row dưới cùng (inline edit). |
BeforePasted | (originRows, copiedRows) |
AfterPasted | (originRows, copiedRows) |
Format cell — FormatCell / FormatRow
GridPolicy.FormatCell / FormatRow được map sang Component.FormatData / FormatEntity lúc render (qua GridPolicy.MapToComponent()):
res.FormatData = header.FormatCell; // FormatCell ⇄ FormatData
res.FormatEntity = header.FormatRow; // FormatRow ⇄ FormatEntity
Sau đó Utils.GetCellTextInternal(component, cellData, row, refData) render text theo logic của ComponentType (xem Cấu hình UI → Logic render cell):
-- Cấu hình cột grid điển hình
INSERT INTO GridPolicy
(FeatureId, ComponentId, EntityId, FieldName, ShortDesc, ComponentType, RefName, FormatCell, [Order]) VALUES
-- Cột Date — dùng {0:format} positional
(42, 100, 12, 'CreatedDate', N'Ngày tạo', 'Datepicker', NULL, '{0:dd/MM/yyyy HH:mm}', 10),
-- Cột FK Customer — RefName trigger LoadMasterData fetch ref entity, FormatCell áp lên ref
(42, 100, 12, 'CustomerId', N'Khách hàng', 'Dropdown', 'Customer', '{Code} - {Name}', 20),
-- Cột Number formatted
(42, 100, 12, 'Total', N'Tổng', 'Number', NULL, '{0:N0}', 30),
-- Cột text với FormatRow ghép nhiều field row
(42, 100, 12, 'OrderNo', N'Mã đơn', NULL, NULL, NULL, 40);
-- (cột thứ 4 set FormatRow trong cột riêng nếu cần — vd '{OrderNo} ({Status.Name})')
LoadMasterData — auto fetch ref entity cho FK cells
Khi grid có cột FK (ComponentType = Dropdown/Select2/SearchEntry/MultipleSearchEntry, RefName set), Core tự động gọi LoadMasterData(rows) sau khi load row data:
- Quét tất cả header có
RefName. - Lấy distinct ids từ rows (vd
CustomerId in (1, 3, 7)). - POST batch
Client.LoadById(...)cho từngRefName→ fetch ref entities trong 1 request. - Cache vào
RefData[refName]. SyncMasterData(rows, headers)— set property nested trên row (vdrow.Customer = customerEntity) → placeholder{Customer.Name}work.
→ Pattern khuyến cáo:
-- ✅ Đúng: set RefName + FormatCell, Core tự lo
RefName: Customer
FormatCell: '{Code} - {Name}'
-- ❌ Sai: tự gọi API ngoài để load Customer rồi tự ghép trong code
Việc của bạn chỉ là cấu hình GridPolicy đúng — RefName, ComponentType, FormatCell. Core lo:
- Fetch ref data (LoadMasterData)
- Cache (RefData)
- Sync vào row (SyncMasterData)
- Render text (GetCellTextInternal)
→ Cú pháp placeholder đầy đủ: Cấu hình UI → FormatData/FormatEntity/FormatCell.
Cấu hình cột (GridPolicy)
Cột grid là bảng riêng GridPolicy, scope theo (FeatureId, ComponentId = id của row GridView):
| Field | Mô tả |
|---|---|
FieldName | Property của row entity. |
ShortDesc | Header label. |
Width | Px. |
Frozen | True → sticky bên trái. |
Sortable | Click header để sort. |
Filterable | Show filter cell dưới header. |
StatusBar | True → cột toolbar (chứa button row action). |
Order | Vị trí cột. |
Active | Hide khi false. |
ComType | Renderer cell (CellText, Number, Datepicker, …). |
FormatCell | Template {FieldName} / {Path.To.Field} áp lên row entity (xem mục Format cell trên). |
FormatRow | Fallback khi FormatCell rỗng. |
Aggregate | "sum" / "avg" / "count" cho summary footer. |
Inline edit
Set Editable = true → grid render thêm 1 empty row cuối cho insert. User gõ vào cell → row promote thành record thật, FK auto-fill từ entity cha.
Khi nào dùng
✅ Tabular list, sort/filter/group cột, master-detail (grid con bind navigation collection).
Variants:
- GroupGridView — group theo field.
- VirtualGrid — render virtualized cho >1k row.
- TreeView — list dạng cây.
Tip
DataSourceFilterphải đủ?$filter=.... Có thể thêm$top,$expand,$orderby.- Để bind grid vào navigation collection của entity cha → set
FieldNamethay vìReference(vdFieldName: Lines).