Keep option groups independent
Build mutually exclusive choices without coupling unrelated decisions.
Group identity matters more than distance on the canvas. Delivery, payment and customer type are independent decisions in this sample. Update the summary from the selected states, and inspect the difference between clicking the already-selected option and changing a value.
Step 1Prepare a safe practice project#
Extract the archive into a new writable folder, separate from your own application. Open OptionGroups.mcproj in McBasic™. Keep every declared source, layout, resource and migration file together.
To reconstruct it yourself, create a DesktopApp project and add the files declared below. In the complete project, follow these steps as a guided rebuild: replace each named source file once and Check after all its procedures are present.
Exact project configuration
{
"schemaVersion": 1,
"projectId": "99578971-5863-4082-a627-ec424196595e",
"name": "OptionGroups",
"kind": "DesktopApp",
"language": {
"dialect": "McBasic1",
"requireExplicit": true,
"compare": "Binary",
"defaultArrayBase": 0
},
"application": {
"bundleIdentifier": "com.mcbasic.optiongroups",
"version": "0.1.0",
"buildNumber": "1",
"startupFormId": "form-main",
"shutdownMode": "OnStartupFormClosed"
},
"forms": [
{
"id": "form-main",
"typeName": "frmMain",
"layout": "Forms/frmMain.form.json",
"code": "Forms/frmMain.bas"
}
],
"modules": [],
"classes": [],
"tests": [],
"references": [],
"resources": [],
"targets": [
"osx-arm64"
],
"capabilities": []
}Step 2Build the Form and set its properties#
frmMain
Select the Form first and set its properties. Add containers before their children. These are initial Designer values, not statements to paste into a procedure.
| Form property | Value |
|---|---|
Caption | "Option groups" |
Width | 620 |
Height | 460 |
| Type | Name | Parent |
|---|---|---|
| Panel | pnlDelivery | Form |
| Panel | pnlPayment | Form |
| OptionButton | optStandard | pnlDelivery |
| OptionButton | optExpress | pnlDelivery |
| OptionButton | optCard | pnlPayment |
| OptionButton | optCash | pnlPayment |
| OptionButton | optPersonal | Form |
| OptionButton | optBusiness | Form |
| Label | lblState | Form |
| Label | lblClick | Form |
| CommandButton | cmdExpress | Form |
pnlDelivery · exact Inspector values
| Property | Value |
|---|---|
Left | 24 |
Top | 44 |
Width | 240 |
Height | 150 |
Enabled | True |
Visible | True |
TabIndex | 0 |
| Anchor edges | Left, Top |
pnlPayment · exact Inspector values
| Property | Value |
|---|---|
Left | 284 |
Top | 44 |
Width | 240 |
Height | 150 |
Enabled | True |
Visible | True |
TabIndex | 1 |
| Anchor edges | Left, Top |
optStandard · exact Inspector values
| Property | Value |
|---|---|
Left | 16 |
Top | 24 |
Width | 200 |
Height | 32 |
Enabled | True |
Visible | True |
Caption | "Standard delivery" |
GroupName | "delivery" |
Checked | True |
TabIndex | 2 |
| Anchor edges | Left, Top |
optExpress · exact Inspector values
| Property | Value |
|---|---|
Left | 16 |
Top | 72 |
Width | 200 |
Height | 32 |
Enabled | True |
Visible | True |
Caption | "Express delivery" |
GroupName | "delivery" |
Checked | False |
TabIndex | 3 |
| Anchor edges | Left, Top |
optCard · exact Inspector values
| Property | Value |
|---|---|
Left | 16 |
Top | 24 |
Width | 200 |
Height | 32 |
Enabled | True |
Visible | True |
Caption | "Card" |
GroupName | "payment" |
Checked | True |
TabIndex | 4 |
| Anchor edges | Left, Top |
optCash · exact Inspector values
| Property | Value |
|---|---|
Left | 16 |
Top | 72 |
Width | 200 |
Height | 32 |
Enabled | True |
Visible | True |
Caption | "Cash" |
GroupName | "payment" |
Checked | False |
TabIndex | 5 |
| Anchor edges | Left, Top |
optPersonal · exact Inspector values
| Property | Value |
|---|---|
Left | 24 |
Top | 220 |
Width | 240 |
Height | 32 |
Enabled | True |
Visible | True |
Caption | "Personal account" |
GroupName | "account" |
Checked | True |
TabIndex | 6 |
| Anchor edges | Left, Top |
optBusiness · exact Inspector values
| Property | Value |
|---|---|
Left | 284 |
Top | 220 |
Width | 240 |
Height | 32 |
Enabled | True |
Visible | True |
Caption | "Business account" |
GroupName | "account" |
Checked | False |
TabIndex | 7 |
| Anchor edges | Left, Top |
lblState · exact Inspector values
| Property | Value |
|---|---|
Left | 24 |
Top | 274 |
Width | 570 |
Height | 42 |
Enabled | True |
Visible | True |
Caption | "Ready" |
TabIndex | 8 |
| Anchor edges | Left, Top |
lblClick · exact Inspector values
| Property | Value |
|---|---|
Left | 24 |
Top | 320 |
Width | 570 |
Height | 32 |
Enabled | True |
Visible | True |
Caption | "Choose an option" |
TabIndex | 9 |
| Anchor edges | Left, Top |
cmdExpress · exact Inspector values
| Property | Value |
|---|---|
Left | 24 |
Top | 366 |
Width | 280 |
Height | 32 |
Enabled | True |
Visible | True |
Caption | "Select express from BASIC" |
TabIndex | 10 |
| Anchor edges | Left, Top |
Step 3Connect the events explicitly#
frmMain
| Object | Event | Procedure | Parameters |
|---|---|---|---|
| Form | Load | Form_Load | () |
Step 4Enter the complete behavior#
Open the named source file. Enter declarations first, then every procedure. Expand a procedure for its full body, or copy the complete file. Helpers are required: do not stop after entering the first Click handler.
Forms/frmMain.bas
Enter these declarations at file scope, before the procedures.
Option ExplicitPrivate Sub UpdateState()
Enter this helper in the named source file, outside every other procedure. Its callers are included in the same project.
Private Sub UpdateState()
lblState.Caption = "Express: " & CStr(optExpress.Checked) & "; Cash: " & CStr(optCash.Checked) & "; Business: " & CStr(optBusiness.Checked)
End SubPublic Sub Form_Load()
Initialize state before enabling dependent actions. Keep the shared declarations and startup dependencies with this procedure.
Public Sub Form_Load()
cmdExpress.Default = True
cmdExpress.Cancel = True
lblClick.Caption = "Named group: " & optStandard.GroupName
Call UpdateState()
End SubPublic Sub cmdExpress_Click()
Enter the complete action, including its input checks and calls to helper procedures.
Public Sub cmdExpress_Click()
optExpress.Checked = True
End SubPublic Sub optStandard_Change()
Read the current value or selection and update its dependent interface. The binding above determines which object calls this handler.
Public Sub optStandard_Change()
Call UpdateState()
End SubPublic Sub optStandard_Click()
Enter the complete action, including its input checks and calls to helper procedures.
Public Sub optStandard_Click()
lblClick.Caption = "Click: optStandard"
End SubPublic Sub optExpress_Change()
Read the current value or selection and update its dependent interface. The binding above determines which object calls this handler.
Public Sub optExpress_Change()
Call UpdateState()
End SubPublic Sub optExpress_Click()
Enter the complete action, including its input checks and calls to helper procedures.
Public Sub optExpress_Click()
lblClick.Caption = "Click: optExpress"
End SubPublic Sub optCard_Change()
Read the current value or selection and update its dependent interface. The binding above determines which object calls this handler.
Public Sub optCard_Change()
Call UpdateState()
End SubPublic Sub optCard_Click()
Enter the complete action, including its input checks and calls to helper procedures.
Public Sub optCard_Click()
lblClick.Caption = "Click: optCard"
End SubPublic Sub optCash_Change()
Read the current value or selection and update its dependent interface. The binding above determines which object calls this handler.
Public Sub optCash_Change()
Call UpdateState()
End SubPublic Sub optCash_Click()
Enter the complete action, including its input checks and calls to helper procedures.
Public Sub optCash_Click()
lblClick.Caption = "Click: optCash"
End SubPublic Sub optPersonal_Change()
Read the current value or selection and update its dependent interface. The binding above determines which object calls this handler.
Public Sub optPersonal_Change()
Call UpdateState()
End SubPublic Sub optPersonal_Click()
Enter the complete action, including its input checks and calls to helper procedures.
Public Sub optPersonal_Click()
lblClick.Caption = "Click: optPersonal"
End SubPublic Sub optBusiness_Change()
Read the current value or selection and update its dependent interface. The binding above determines which object calls this handler.
Public Sub optBusiness_Change()
Call UpdateState()
End SubPublic Sub optBusiness_Click()
Enter the complete action, including its input checks and calls to helper procedures.
Public Sub optBusiness_Click()
lblClick.Caption = "Click: optBusiness"
End SubCopy the complete Forms/frmMain.bas file
Replace the file once; do not append duplicate procedures.
Option Explicit
Private Sub UpdateState()
lblState.Caption = "Express: " & CStr(optExpress.Checked) & "; Cash: " & CStr(optCash.Checked) & "; Business: " & CStr(optBusiness.Checked)
End Sub
Public Sub Form_Load()
cmdExpress.Default = True
cmdExpress.Cancel = True
lblClick.Caption = "Named group: " & optStandard.GroupName
Call UpdateState()
End Sub
Public Sub cmdExpress_Click()
optExpress.Checked = True
End Sub
Public Sub optStandard_Change()
Call UpdateState()
End Sub
Public Sub optStandard_Click()
lblClick.Caption = "Click: optStandard"
End Sub
Public Sub optExpress_Change()
Call UpdateState()
End Sub
Public Sub optExpress_Click()
lblClick.Caption = "Click: optExpress"
End Sub
Public Sub optCard_Change()
Call UpdateState()
End Sub
Public Sub optCard_Click()
lblClick.Caption = "Click: optCard"
End Sub
Public Sub optCash_Change()
Call UpdateState()
End Sub
Public Sub optCash_Click()
lblClick.Caption = "Click: optCash"
End Sub
Public Sub optPersonal_Change()
Call UpdateState()
End Sub
Public Sub optPersonal_Click()
lblClick.Caption = "Click: optPersonal"
End Sub
Public Sub optBusiness_Change()
Call UpdateState()
End Sub
Public Sub optBusiness_Click()
lblClick.Caption = "Click: optBusiness"
End SubStep 5Keep resources and storage reproducible#
No external resource or migration files are declared. Any inline migration, seed data or local JSON is present in the code above. Runtime application data and private preferences are not included in the archive.
Step 6Check, run and test the result#
Save all files and run Check. Resolve diagnostics before Run. Developer CLI users can work from the extracted folder:
mcbasic check OptionGroups.mcproj
mcbasic run OptionGroups.mcprojAcceptance checklist
- Change delivery without changing payment.
- Click an already-selected option and compare Click with Change.
- Use the Express command to select an option programmatically.
Step 7Make one change and repeat the tests#
Add another delivery choice while preserving the other two groups.
Save a working Git checkpoint first. Change one behavior, Check again and repeat the acceptance checklist. Compare with the downloaded solution if a regression appears.
20f4bfed6b · Build manifest