Events
Two ways to react to the grid: callbacks (one hook each) and the
event bus (one stream for all of them). Both are usable from any repo
that imports package:bcell/bcell.dart.
Callbacks
Pass them straight to BCellGrid:
BCellGrid(
columns: cols,
rows: rows,
onLoaded: (e) => _sm = e.stateManager, // grid is ready
onChanged: (e) => print('${e.oldValue} -> ${e.value} at row ${e.rowIdx}'),
onSelected: (e) => print('selected ${e.cell?.value}'),
onSorted: (e) => print('sorted ${e.column.title}, was ${e.oldSort}'),
)
Event fields:
| Event | Fields |
|---|---|
BCellGridOnLoadedEvent | stateManager |
BCellGridOnChangedEvent | columnIdx, column, rowIdx, row, value, oldValue |
BCellGridOnSelectedEvent | row?, rowIdx?, cell? (all null when cleared) |
BCellGridOnSortedEvent | column, oldSort |
Event bus (one stream, all events)
The bus is a stdlib StreamController.broadcast() — subscribe once and get
every event, switch on the type. Cancel the subscription in dispose.
StreamSubscription<BCellGridEvent>? _sub;
BCellGrid(
columns: cols,
rows: rows,
onLoaded: (e) {
_sub = e.stateManager.eventManager.listener((event) {
switch (event) {
case BCellGridOnLoadedEvent():
// ready
case BCellGridOnChangedEvent(:final value, :final rowIdx):
// a cell changed
case BCellGridOnSelectedEvent(:final cell):
// selection moved (cell is null when cleared)
case BCellGridOnSortedEvent(:final column):
// a column sort changed
default:
// your own custom events land here too (see below)
}
});
},
);
void dispose() {
_sub?.cancel();
super.dispose();
}
Emit your own events ("create event, then use event")
BCellGridEvent is an open interface. Define your own event class and
emit it through the manager — every listener receives it. This lets a
host app push its domain events onto the same stream the grid uses.
// 1. Create an event type.
class RowFlaggedEvent implements BCellGridEvent {
const RowFlaggedEvent(this.rowIdx);
final int rowIdx;
}
// 2. Emit it (e.g. from a button, a service callback, anywhere with the manager).
stateManager.emit(RowFlaggedEvent(3));
// 3. Use it — the same listener above catches it in `default`, or match the type:
_sub = stateManager.eventManager.listener((event) {
if (event is RowFlaggedEvent) {
// react to your own event
}
});
emit is a no-op until someone has accessed eventManager to subscribe,
so grids that never listen pay nothing.