Screen Bindings
The sample's UI splits into two parts.
| Screen | Role | Core bindings |
|---|---|---|
| ViewRun | Main — DataGrid + 6 buttons | Data::DispData (rows array) · Data::SelectIndex (selected index) |
| ModifyDlg | Record-edit dialog | Data::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:
| Property | Value | Meaning |
|---|---|---|
| ItemsSourceDataName | Data::DispData | The row array the data grid displays |
| SelectIndexDataName | Data::SelectIndex | When 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.
| Index | Header | Format / Width recommended |
|---|---|---|
| 0 | id | width 60 |
| 1 | order_no | width 90 |
| 2 | menu_name | width 120 |
| 3 | start_time | width 160 |
| 4 | end_time | width 160 |
| 5 | weight_g | format 0.0, width 80 |
| 6 | result | width 80 |
| 7 | is_error | width 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 control | DataName | Recommend readonly |
|---|---|---|
| Id display | Data::EditId | ✓ |
| Order No input | Data::EditOrderNo | |
| Menu input | Data::EditMenuName | |
| Start time | Data::EditStartTime | ✓ |
| End time | Data::EditEndTime | |
| Weight (g) | Data::EditWeightG | |
| Result | Data::EditResult | |
| Error checkbox | Data::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:
- DB → Edit fields copy (before showing the dialog)
GUI.ShowDialog—true(OK) /false(Cancel)- Edit fields → DB UPDATE (
DB_UpdateModified)
GUI.ShowDialog OK / Cancel
The two dialog buttons each carry a DialogResult property.
| Button | DialogResult | Effect |
|---|---|---|
| OK | true | ShowDialog returns true and the dialog closes |
| Cancel | false | ShowDialog 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"
| Variable | Control property | Effect |
|---|---|---|
DispData (array string) | XDataGrid.ItemsSourceDataName | DataGrid rows |
SelectIndex (int) | XDataGrid.SelectIndexDataName | Selected row 0..N-1 / -1 |
Edit* (8 of them) | Dialog control DataName | ModifyDlg two-way |
DbStatusText (string) | XLabel.DataName | Status 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).