Database Manual · Chapter 7

Screen Bindings

The sample's UI splits into two parts.

ScreenRoleCore bindings
ViewRunMain — DataGrid + 6 buttonsData::DispData (rows array) · Data::SelectIndex (selected index)
ModifyDlgRecord-edit dialogData::EditId · EditOrderNo · EditMenuName · EditEndTime and 5 more

Scripts only update data (array DispData[], int EditWeightG, …); the controls re-paint themselves to follow — that wiring is the heart of this chapter.


1) ViewRun · XDataGrid Binding

Data.xms declares two variables:

// One CSV line = one row (id,order_no,menu_name,start_time,end_time,weight_g,result,is_error)
array DispData[] = {"",};
 
// XDataGrid auto-updates this with the current selected row index (-1 = none)
int SelectIndex = -1;

Set two properties on the XDataGrid in the Property Editor:

PropertyValueMeaning
ItemsSourceDataNameData::DispDataThe row array the data grid displays
SelectIndexDataNameData::SelectIndexWhen user picks a row, this gets 0..N-1; -1 = no selection

CSV row format

Each element of DispData is one comma-joined string:

"42,O1042,Latte,2026-05-06 09:31:02,2026-05-06 09:31:30,300,Done,0"

The end of DB_Refresh() builds this format directly from GetRowArray(i).

Columns definition

If the DataGrid's Columns property defines the same 8 columns, the N-th token of CSV maps automatically to the N-th column.

IndexHeaderFormat / Width recommended
0idwidth 60
1order_nowidth 90
2menu_namewidth 120
3start_timewidth 160
4end_timewidth 160
5weight_gformat 0.0, width 80
6resultwidth 80
7is_errorwidth 60

Refresh flow

The script just does DispData.Clear() → repeated Add(). Each line built in DB_Refresh() is pushed into DispData and the screen re-paints automatically.

DispData.Clear();
for( i, 0, rows-1 )
{
   array row = DB["local"].GetRowArray(i);
   DispData.Add($"{row[0]},{row[1]},{row[2]},{row[3]},{row[4]},{row[5]},{row[6]},{row[7]}");
}

2) ModifyDlg — Dialog with Two-way Binding

ModifyDlg is a screen whose ViewModule type is Dialog.

8 edit fields

The variables declared in Data.xms are bound 1:1 to the dialog's input controls.

// Data.xms excerpt
int    EditId        = 0;        // PK (read-only display)
string EditOrderNo   = "";
string EditMenuName  = "";
string EditStartTime = "";       // read-only display
string EditEndTime   = "";
double EditWeightG   = 0.0;
string EditResult    = "";
int    EditIsError   = 0;

If you set the DataName property of each XTextBox / XNumberBox / XCheckBox in the dialog to these variable names, user input is automatically written back into Data::Edit*.

Dialog controlDataNameRecommend readonly
Id displayData::EditId
Order No inputData::EditOrderNo
Menu inputData::EditMenuName
Start timeData::EditStartTime
End timeData::EditEndTime
Weight (g)Data::EditWeightG
ResultData::EditResult
Error checkboxData::EditIsError

Calling the dialog

DB_OpenModifyDlg(), called by the Modify button, shows the canonical pattern.

FUNCTION DB_OpenModifyDlg()
{
   // (guards omitted)
 
   // 1) Copy selected row values into edit fields
   EditId        = DB["local"].GetValueInt(SelectIndex, "id");
   EditOrderNo   = DB["local"].GetValue   (SelectIndex, "order_no");
   EditMenuName  = DB["local"].GetValue   (SelectIndex, "menu_name");
   EditStartTime = DB["local"].GetValue   (SelectIndex, "start_time");
   EditEndTime   = DB["local"].GetValue   (SelectIndex, "end_time");
   EditWeightG   = DB["local"].GetValueDouble(SelectIndex, "weight_g");
   EditResult    = DB["local"].GetValue   (SelectIndex, "result");
   EditIsError   = DB["local"].GetValueInt(SelectIndex, "is_error");
 
   // 2) Show dialog — blocks until user clicks OK / Cancel
   if( GUI.ShowDialog(/*viewModuleName*/"ModifyDlg") == false )
   {
      Log($"DB_OpenModifyDlg : cancelled by user");
      return false;
   }
 
   // 3) On OK, UPDATE with the edited values
   return DB_UpdateModified();
}

Three crisply separated steps:

  1. DB → Edit fields copy (before showing the dialog)
  2. GUI.ShowDialogtrue (OK) / false (Cancel)
  3. Edit fields → DB UPDATE (DB_UpdateModified)

GUI.ShowDialog OK / Cancel

The two dialog buttons each carry a DialogResult property.

ButtonDialogResultEffect
OKtrueShowDialog returns true and the dialog closes
CancelfalseShowDialog returns false and the dialog closes

This one-line agreement keeps the calling code simple.


3) Status Label — DbStatusText

Data.xms declares one plain string:

string DbStatusText = "● CLOSED";

If ViewRun's top-right XLabel has its DataName set to Data::DbStatusText, simply switching the value to "● OPEN" in DB_Open() and "● CLOSED" in DB_Close() makes the screen track automatically.


Summary — "Update data and the screen follows"

VariableControl propertyEffect
DispData (array string)XDataGrid.ItemsSourceDataNameDataGrid rows
SelectIndex (int)XDataGrid.SelectIndexDataNameSelected row 0..N-1 / -1
Edit* (8 of them)Dialog control DataNameModifyDlg two-way
DbStatusText (string)XLabel.DataNameStatus text

The script just touches variables — that's it. This is QMachineStudio's data-first GUI paradigm. The next chapter ties everything together with events (button clicks).