Skip to content
ModernUI A DaneTrades developer library

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

UI build fragment
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 BindRow only for visible row slots, not once per data row.
  • Always reset optional slots (ResetSlotsBeforeBind() on MuiRowTemplate) 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 not delete the 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

UI build fragment
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

UI build fragment
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; MuiTableView does 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

UI build fragment
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() when BindRow is cheap.
  • Call NotifyChanged() on the source after bulk updates instead of recreating the list.
  • Fixed RowHeight keeps scroll and hit-testing predictable.

Example

Reference excerpt
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

UI build fragment
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 explicit ColWidth for key columns and ColFlex for stretch columns.
  • CellText should return display strings only — avoid heavy work per cell during paint.

Example

Reference excerpt
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

UI build fragment
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

Reference excerpt
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

UI build fragment
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 / MuiTableView do not own the source.
  • Keep MuiListBox / MuiSimpleTable (or at least .source) alive while editing.
  • Delete source on shutdown if you need explicit cleanup after removing the view.

See Table and list sources for SetItem, Refresh, SetCell, and row helpers.

Related


Related Pages