Data views
Data views display rows, columns, lists, and tree structures. They usually depend on a source object that supplies row content.
Controls And Sources
| Control/helper | Use it for | Emits events |
|---|---|---|
MuiListView |
Virtualized/custom list rows. | MUI_EVENT_SELECTION_CHANGED only (no MUI_EVENT_ITEM_CLICK on bus) |
MuiTableView |
Data table with columns, rows, selection, cell clicks, and header clicks. | MUI_EVENT_SELECTION_CHANGED, MUI_EVENT_ITEM_CLICK, MUI_EVENT_TABLE_CELL_CLICK, MUI_EVENT_TABLE_CELL_DOUBLE_CLICK, MUI_EVENT_TABLE_HEADER_CLICK |
MuiTreeView |
Hierarchical rows with expand/collapse. | MUI_EVENT_SELECTION_CHANGED, MUI_EVENT_ITEM_CLICK, MUI_EVENT_ITEM_DOUBLE_CLICK, MUI_EVENT_EXPANDED_CHANGED |
MuiItemSource |
Base source for list row binding. | None |
MuiTableSource |
Base source for table rows/columns. | None |
MuiSimpleTableSource |
Simple in-memory table source. | None |
MuiTreeSource |
Base source for tree data. | None |
MuiRowTemplate |
Row composition container for list rows. | None by default |
Mui::ListBox |
String-list wrapper. | Through contained MuiListView |
Mui::SimpleTable |
Simple table wrapper. | Through contained MuiTableView |
Event Fields
| Event | Useful fields |
|---|---|
MUI_EVENT_SELECTION_CHANGED |
Index(), Row(), Value(), Text() where available |
MUI_EVENT_ITEM_CLICK |
Index(), Row(), Text() |
MUI_EVENT_ITEM_DOUBLE_CLICK |
Index(), Text() |
MUI_EVENT_TABLE_CELL_CLICK |
Row(), Col(), Text() |
MUI_EVENT_TABLE_CELL_DOUBLE_CLICK |
Row(), Col(), Text() |
MUI_EVENT_TABLE_HEADER_CLICK |
Index(), Col(), Text() |
MUI_EVENT_EXPANDED_CHANGED |
Index(), Expanded(), Text() |
App-level events require .Id(...) ≥ 0. See Event Bus.
List vs table: MuiListView emits MUI_EVENT_SELECTION_CHANGED only (no MUI_EVENT_ITEM_CLICK on the bus). MuiTableView emits row/cell/header events as listed below.
Source Ownership And Refresh
Data views read from sources the application owns. The view registers a non-owned observer; it does not delete your source.
| Rule | Detail |
|---|---|
| Lifetime | Keep each MuiItemSource / MuiTableSource / MuiTreeSource alive at least as long as the bound view. |
| Updates | After mutating source data, call NotifyChanged() on MuiBindableSource (or wrapper Refresh()). |
| Wrappers | MuiListBox and MuiSimpleTable heap-allocate sources; keep the struct or source pointer while editing. |
| Row pool | MuiListView owns pooled MuiRowTemplate / custom row elements; do not delete pooled rows from app code. |
Deeper patterns: Table and list sources.
MuiItemSource
Purpose
Abstract data contract for MuiListView. Supplies item count and binds each visible row slot to a source index.
Source: Controls/Data/ItemSource.mqh (extends MuiBindableSource).
Implement It
class CMyListSource : public MuiItemSource
{
public:
virtual int Count(void)
{
return ArraySize(m_rows);
}
virtual void BindRow(MuiRowTemplate *row,const int index)
{
if(row==NULL) return;
row.ResetSlotsBeforeBind();
row.primary.Text(m_rows[index].title);
if(m_rows[index].status!="")
{
row.badge.Text(m_rows[index].status);
row.badge.SetVisible(true);
}
}
};
Events
None. Views emit events; sources only notify observers via NotifyChanged().
Key API
| Method | Purpose |
|---|---|
Count() |
Total logical items (required). |
BindRow(row, index) |
Fill pooled MuiRowTemplate (default path). |
GetRowKey(index) |
Optional stable row key (default = index). |
HasCustomRows() / CreateRow() / BindRowElement() |
Custom row element path instead of MuiRowTemplate. |
NotifyChanged() |
From MuiBindableSource; triggers view relayout/rebind. |
Notes
- Virtualized lists call
BindRowonly for visible row slots, not once per data row. - Always reset optional slots (
ResetSlotsBeforeBind()onMuiRowTemplate) to avoid stale pooled state.
Related
MuiRowTemplate
Purpose
Default reusable row layout for list sources: primary, optional secondary, badge, and meta slots in a horizontal row.
Source: Controls/Data/RowTemplate.mqh.
Create It
You do not construct MuiRowTemplate in EA code for normal usage. MuiListView creates and pools instances; your source fills them in BindRow().
Events
None by default.
Common Setters (in BindRow)
| Slot | Typical use |
|---|---|
row.primary.Text(...) |
Main label (flex width). |
row.secondary.Text(...) + .SetVisible(true) |
Short right-cluster text. |
row.badge.Text(...) + .SetVisible(true) |
Status chip. |
row.meta.Text(...) + .SetVisible(true) |
Small right-aligned meta text. |
row.ResetSlotsBeforeBind() |
Clear optional slots before binding a new index. |
Notes
- Same template instance is rebound to many indices while scrolling — set every field you rely on each time.
- Owned by the list view row pool; configure in
BindRow, do notdeletethe template.
Related
MuiTableSource
Purpose
Abstract data contract for MuiTableView: row/column dimensions, column names, and cell text. Optional SortBy for header-click sorting.
Source: Controls/Data/TableView.mqh (MuiTableSource class; extends MuiBindableSource).
Implement It
class CMyTableSource : public MuiTableSource
{
public:
virtual int RowCount(void) { return m_rowCount; }
virtual int ColCount(void) { return 3; }
virtual string ColName(const int col) { return m_colNames[col]; }
virtual string CellText(const int row,const int col)
{
return m_cells[row][col];
}
virtual void SortBy(const int col,const bool ascending)
{
// optional: reorder m_cells, then NotifyChanged()
}
};
Events
None. The table view emits UI events.
Key API
| Method | Purpose |
|---|---|
RowCount(), ColCount() |
Grid size (required). |
ColName(col) |
Header label. |
CellText(row, col) |
Cell display string. |
SortBy(col, ascending) |
Optional; called when user sorts via header. |
NotifyChanged() |
Refresh bound table after data edits. |
Related
MuiSimpleTableSource
Purpose
In-memory string grid implementing MuiTableSource. Used by Mui::SimpleTable and MuiCreate::SimpleTableSource.
Source: Controls/Data/TableView.mqh.
Create It
string headers[];
ArrayResize(headers,3);
headers[0]="Symbol";
headers[1]="Side";
headers[2]="PnL";
MuiSimpleTableSource *src=MuiCreate::SimpleTableSource(headers);
string row[];
ArrayResize(row,3);
row[0]="EURUSD"; row[1]="Buy"; row[2]="12.5";
MuiCreate::AddTableRow(src,row);
MuiTableView *tv=Mui::TableView(parent,src,520.0,260.0);
tv.Id(APP_TABLE_POSITIONS);
Or use MuiSimpleTable table=Mui::SimpleTable(parent, headers, rows, ...).
Events
None (table view emits events).
Common API
| Method | Purpose |
|---|---|
AddColumn(name) |
Add column (notifies). |
AddRow(cells[]) |
Append row. |
SetCellText(row, col, value) |
Update one cell. |
SetRow(row, cells[]) |
Replace row. |
InsertRow, RemoveRow, ClearRows |
Row structure changes (see source). |
SortBy(col, ascending) |
Built-in string sort. |
CellText, ColName, RowCount, ColCount |
MuiTableSource implementation. |
Notes
- Application owns the source;
MuiTableViewdoes not delete it. - After bulk edits,
NotifyChanged()runs automatically from setters that mutate data.
Related
MuiTreeSource
Purpose
Abstract contract for MuiTreeView: flattened visible rows with depth, expand state, and toggle.
Source: Controls/Data/TreeView.mqh.
Key API
| Method | Purpose |
|---|---|
VisibleCount() |
Rows currently visible (expanded tree flattening). |
VisibleText(visibleIndex) |
Label for visible row. |
VisibleDepth, VisibleHasChildren, VisibleIsExpanded |
Layout and chevron behaviour. |
VisibleToggleExpanded(visibleIndex) |
Expand/collapse node. |
NotifyChanged() |
Refresh tree after structure changes. |
Events
None (tree view emits events). Indices in tree events are visible-row indices, not stable node IDs unless you map them in your source.
Related
MuiListView
Purpose
Virtualized list: a small pool of row templates bound to visible indices. Use with custom MuiItemSource or Mui::ListBox for simple strings.
Source: Controls/Data/ListView.mqh.
Create It
CMyListSource *src=new CMyListSource();
MuiListView *list=Mui::ListView(parent,src,260.0,200.0);
list.Id(APP_LIST_SYMBOLS);
MuiCreate::ListView(parent, x, y, w, h, source) for explicit bounds.
Simple strings: MuiListBox lb=Mui::ListBox(parent, items, selectedIndex, w, h).
Events
| Event | When it fires | Useful fields |
|---|---|---|
MUI_EVENT_SELECTION_CHANGED |
User click on a row, or programmatic Selected(index) / ClearSelection() |
ControlId(), Index(), Value() (index). No Text() on list selection events. |
MuiListView does not emit MUI_EVENT_ITEM_CLICK on the event bus. Item/double-click intent handlers exist for advanced/legacy use only.
Common Setters
| Setter | Purpose |
|---|---|
.Source(src) |
Attach non-owned MuiItemSource. |
.Selected(index) / .ClearSelection() |
Selection (-1 = none); fires MUI_EVENT_SELECTION_CHANGED. |
.RowHeight(h) |
Logical row height for hit-testing and virtualization. |
.ScrollTo(y) / .ScrollBy(dy) |
Vertical scroll. |
.NotifySourceDataChanged() |
Clamp selection/scroll after external source edits. |
.BgColor, .BorderColor, .BorderVisible, .Id(...) |
Chrome and routing. |
Common Reads
| Getter | Purpose |
|---|---|
.Count() |
source.Count(). |
.SelectedIndex() / .Selected() |
Current index or -1. |
.HasSelection() |
Whether index is valid. |
Performance notes
- Only visible rows are bound each frame/layout — suitable for large
Count()whenBindRowis cheap. - Call
NotifyChanged()on the source after bulk updates instead of recreating the list. - Fixed
RowHeightkeeps scroll and hit-testing predictable.
Example
if(event.EventId()==MUI_EVENT_SELECTION_CHANGED && event.ControlId()==APP_LIST_SYMBOLS)
{
const int ix=event.Index();
if(ix>=0)
LoadSymbol(ix);
}
Related
MuiTableView
Purpose
Virtualized data table: sortable header, column widths/flex, row selection (optional multi-select), horizontal/vertical scroll, cell and header interaction.
Source: Controls/Data/TableView.mqh.
Create It
MuiTableView *tv=Mui::TableView(parent,src,520.0,260.0);
tv.Id(APP_TABLE_TRADES);
tv.ColWidth(0,120.0);
tv.ColFlex(1,1.0);
tv.ShowGrid(true);
tv.SelectionEnabled(true);
MuiCreate::Table(parent, x, y, w, h, source, scrollable) or MuiCreate::Table + MuiTableConfig.
Events
| Event | When it fires | Useful fields |
|---|---|---|
MUI_EVENT_SELECTION_CHANGED |
Row selection changes (click or programmatic) | ControlId(), Index(), Row(), Value() (primary row) |
MUI_EVENT_ITEM_CLICK |
Body row clicked (in addition to selection logic) | ControlId(), Index(), Row(), Value() |
MUI_EVENT_TABLE_CELL_CLICK |
Body click with resolved column | Row(), Col(), Text() (cell text), Value() (row) |
MUI_EVENT_TABLE_HEADER_CLICK |
Header click (also sorts via source.SortBy) |
Index(), Col(), Text() (column name), Value() (col) |
MUI_EVENT_TABLE_CELL_DOUBLE_CLICK |
Cell double-click | Row(), Col(), Text() |
Important: MUI_EVENT_TABLE_CELL_DOUBLE_CLICK is emitted only when SetCellDoubleClickedHandler(...) is set to a non-NULL handler (the view early-outs otherwise). For event-bus-only code, assign a minimal handler or use single-click/cell-click events.
Header click calls MuiTableSource::SortBy when implemented.
Common Setters
| Setter | Purpose |
|---|---|
.Source(src) |
Attach non-owned table source. |
.SelectedRow(row) / .ClearSelection() |
Primary row selection. |
.MultiSelect(true) |
Ctrl+click toggles rows (GetSelectedRows). |
.SelectionEnabled(false) |
Disable row selection (sort/scroll still work). |
.ColWidth(col, w), .ColFlex(col, flex), .ColWidths(array) |
Column layout. |
.RowHeight, .HeaderHeight, .ShowGrid, .AltRowBg, border/colour setters |
Appearance. |
.ScrollableX/Y, .BodyScrollY, .BodyScrollX |
Scrolling. |
.NotifySourceDataChanged() |
Clamp scroll/selection after source changes. |
Common Reads
| Getter | Purpose |
|---|---|
.RowCount(), .ColCount(), .ColName, .CellText |
Pass-through from source. |
.SelectedRow(), .SelectedCellText(col) |
Selection helpers. |
Performance notes
- Body uses a virtualized cell pool (visible rows × columns), not one widget per data row.
- Prefer
NotifyChanged()over destroying/recreating the table for updates. - Very wide tables: enable
ScrollableX; assign explicitColWidthfor key columns andColFlexfor stretch columns. CellTextshould return display strings only — avoid heavy work per cell during paint.
Example
void CPanel::OnMuiEvent(MuiRoot &root,const MuiEventData &event)
{
if(event.ControlId()!=APP_TABLE_TRADES)
return;
if(event.EventId()==MUI_EVENT_TABLE_CELL_CLICK)
{
const int r=event.Row();
const int c=event.Col();
const string cell=event.Text();
}
else if(event.EventId()==MUI_EVENT_TABLE_HEADER_CLICK)
{
const string colName=event.Text();
}
else if(event.EventId()==MUI_EVENT_SELECTION_CHANGED)
{
const int row=event.Row();
}
}
Related
MuiTreeView
Purpose
Virtualized hierarchical list using a flattened visible-row model from MuiTreeSource. Supports expand/collapse gutter, selection, and double-click.
Source: Controls/Data/TreeView.mqh.
Create It
CMyTreeSource *src=new CMyTreeSource();
MuiTreeView *tree=Mui::TreeView(parent,src,360.0,220.0);
tree.Id(APP_TREE_NAV);
MuiCreate::TreeView(parent, x, y, w, h, source) for explicit bounds.
Events
| Event | When it fires | Useful fields |
|---|---|---|
MUI_EVENT_SELECTION_CHANGED |
Visible row becomes selected (body click, not expander-only toggle) | ControlId(), Index() (visible index), Value() |
MUI_EVENT_ITEM_CLICK |
Any qualifying row click (including expander gutter path) | Index(), Text() (visible row label), Value() |
MUI_EVENT_ITEM_DOUBLE_CLICK |
Row double-click | Index(), Text() |
MUI_EVENT_EXPANDED_CHANGED |
Expander toggled and expanded state changed | Index(), Expanded(), Text(), Value() (1/0) |
Text() on tree events is VisibleText(index).
Common Setters
| Setter | Purpose |
|---|---|
.Source(src) |
Attach non-owned MuiTreeSource. |
.Selected(visibleIndex) |
Programmatic selection (fires selection handler path when changed). |
.ClearSelection() |
Clear select state. |
.RowHeight(h) |
Logical row height. |
.NotifySourceDataChanged() |
After source structure/visibility changes. |
.BgColor, .BorderColor, .Id(...) |
Chrome and routing. |
Common Reads
| Getter | Purpose |
|---|---|
.VisibleCount() |
Flattened visible rows. |
.VisibleText(i), .SelectedText() |
Labels. |
.Selected() |
Selected visible index. |
Performance notes
- Virtualized visible-row pool (similar to list).
- Rebuild visible list in the source efficiently; call
NotifyChanged()once per logical tree mutation batch.
Example
if(event.EventId()==MUI_EVENT_EXPANDED_CHANGED && event.ControlId()==APP_TREE_NAV)
{
const bool expanded=event.Expanded();
const string nodeLabel=event.Text();
}
Related
MuiSimpleTable and MuiListBox
Purpose
Fast wrapper structs from Factory/Factory.mqh that pair a view with a heap-allocated simple source.
| Wrapper | Contains | Use when |
|---|---|---|
MuiListBox |
list (MuiListView*), source (MuiStringArrayItemSource*) |
Small string lists |
MuiSimpleTable |
table (MuiTableView*), source (MuiSimpleTableSource*) |
Small string tables |
Create It
MuiListBox lb=Mui::ListBox(parent,items,0,260.0,200.0);
lb.list.Id(APP_LIST_BOX);
MuiSimpleTable st=Mui::SimpleTable(parent,headers,10,520.0,180.0,true,true);
st.table.Id(APP_TABLE_SIMPLE);
st.SetCell(0,0,"EURUSD");
Events
Emitted by the contained list or table (assign .Id(...) on lb.list / st.table).
Ownership
MuiListView/MuiTableViewdo not own the source.- Keep
MuiListBox/MuiSimpleTable(or at least.source) alive while editing. - Delete
sourceon shutdown if you need explicit cleanup after removing the view.
See Table and list sources for SetItem, Refresh, SetCell, and row helpers.