Runtime controls manipulation

Erel

B4X founder
Staff member
Licensed User
Longtime User
Basic4ppc allows you to add controls with the visual designer or at runtime using the AddControls keywords.
Usually it is easier to add the controls with the designer and this also enables the pop-up lists to show when you write the control's name followed by a period.
However there are some occasions when adding controls at runtime is useful.
For example:
B4X:
[COLOR=#0000ff]Sub [/COLOR]App_Start
 Form1.Show
[COLOR=#0000ff] For[/COLOR] i = [COLOR=#800080]1 [/COLOR][COLOR=#0000ff]To [/COLOR][COLOR=#800080]10[/COLOR]
[COLOR=#0000ff]  AddButton[/COLOR]([COLOR=#800000]"Form1"[/COLOR],[COLOR=#800000]"Btn"[/COLOR] & i, [COLOR=#800080]100[/COLOR],[COLOR=#800080]25[/COLOR] * i,[COLOR=#800080]50[/COLOR],[COLOR=#800080]20[/COLOR],i)
[COLOR=#0000ff]  AddEvent[/COLOR]([COLOR=#800000]"Btn"[/COLOR] & i,Click, [COLOR=#800000]"Btn_Click"[/COLOR])
[COLOR=#0000ff] Next[/COLOR]
[COLOR=#0000ff]End Sub[/COLOR]
 
[COLOR=#0000ff]Sub [/COLOR]Btn_Click
[COLOR=#0000ff] Sender[/COLOR].Color = cRed
[COLOR=#0000ff]End Sub[/COLOR]
In this code we are adding 10 buttons to the form.
AddEvent is very important when adding many controls.
We could create Sub Btn1_Click, Sub Btn2_Click... and it would have worked.
Instead we are using AddEvent which connects the Click event of the buttons to a specific sub (Btn_Click).
Note that you can use AddEvent with controls that you create with the designer as well.
Another thing you should notice is that the sub signature (number of parameters) must match the signature of the original event.

If one sub handles events of many controls, we need a way to find which control raised the event. Sender keyword comes to the rescue.
If we just use Sender then it returns the name of the control that raised the event.
However Sender can do more than that. You can treat Sender as a control.
In our example we wrote Sender.Color = cRed, that will change the color of each pressed button to red.
Another important keyword is Control.
Using Control keyword you can reference a control with a string.
If we want to change the color of all buttons to blue when they were first created, we could have written:
B4X:
[COLOR=#0000ff]Sub [/COLOR]App_Start
 Form1.Show
[COLOR=#0000ff] For[/COLOR] i = [COLOR=#800080]1[/COLOR][COLOR=#0000ff]To[/COLOR][COLOR=#800080]10[/COLOR]
[COLOR=#0000ff]  AddButton[/COLOR]([COLOR=#800000]"Form1"[/COLOR],[COLOR=#800000]"Btn"[/COLOR] & i, [COLOR=#800080]100[/COLOR],25 * i,[COLOR=#800080]50[/COLOR],[COLOR=#800080]20[/COLOR],i)
[COLOR=#0000ff]  AddEvent[/COLOR]([COLOR=#800000]"Btn"[/COLOR] & i,Click, [COLOR=#800000]"Btn_Click"[/COLOR])
[COLOR=#0000ff] Next[/COLOR]
 Btn1.Color = cBlue
 Btn2.Color = cBlue
 ...
[COLOR=#0000ff]End Sub[/COLOR]
Instead we could use the Control keyword:
B4X:
[COLOR=#0000ff]Sub [/COLOR]App_Start
 Form1.Show
[COLOR=#0000ff] For[/COLOR] i = [COLOR=#800080]1[/COLOR][COLOR=#0000ff]To[/COLOR][COLOR=#800080]10[/COLOR]
[COLOR=#0000ff]  AddButton[/COLOR]([COLOR=#800000]"Form1"[/COLOR],[COLOR=#800000]"Btn"[/COLOR] & i, [COLOR=#800080]100[/COLOR],[COLOR=#800080]25[/COLOR] * i,[COLOR=#800080]50[/COLOR],[COLOR=#800080]20[/COLOR],i)
[COLOR=#0000ff]  AddEvent[/COLOR]([COLOR=#800000]"Btn"[/COLOR] & i,Click, [COLOR=#800000]"Btn_Click"[/COLOR])
[COLOR=#0000ff]  Control[/COLOR]([COLOR=#800000]"Btn"[/COLOR] & i).Color = cBlue
[COLOR=#0000ff] Next[/COLOR]
[COLOR=#0000ff]End Sub[/COLOR]
Again you should be aware that Control, AddEvent and Sender keywords could be used with controls (and objects) that were added with the designer.
Deleting a control is done with each control's Dispose method.
Two new related functions were added in version 5.50:
GetControls and ControlType.
GetControls returns an array holding the names of all the controls or all the controls that belong to a specific form.
GetControls("") will return all controls, while GetControls("Form1") will return all the controls that belong to Form1.
ControlType returns the type of a control.
Combining GetControls and ControlType allows us to handle all the controls which are of the same type.

Here is an example of a simple numpad:

B4X:
[COLOR=#0000ff]Sub [/COLOR]Globals
[COLOR=#0000ff] Dim[/COLOR] controls([COLOR=#800080]0[/COLOR]) [COLOR=#008000]'Creates an empty array.[/COLOR]
[COLOR=#0000ff]End Sub[/COLOR]
 
[COLOR=#0000ff]Sub [/COLOR]App_Start
 Form1.Show
[COLOR=#0000ff] For[/COLOR] i = [COLOR=#800080]1[/COLOR][COLOR=#0000ff]To[/COLOR][COLOR=#800080]11[/COLOR]
[COLOR=#0000ff]  AddEvent[/COLOR]([COLOR=#800000]"Button"[/COLOR] & i,Click,[COLOR=#800000]"RegularButton_Click"[/COLOR])
[COLOR=#0000ff] Next[/COLOR]
[COLOR=#0000ff]End Sub[/COLOR]
 
[COLOR=#0000ff]Sub [/COLOR]RegularButton_Click
 TextBox1.Text = TextBox1.Text & [COLOR=#0000ff]Sender[/COLOR].Text [COLOR=#008000]'Sender.Text is equivalent to Control(Sender).Text[/COLOR]
[COLOR=#0000ff]End Sub[/COLOR]
 
[COLOR=#0000ff]Sub [/COLOR]chkEnabled_Click
 controls() = [COLOR=#0000ff]GetControls[/COLOR]([COLOR=#800000]"Form1"[/COLOR])
[COLOR=#0000ff] For[/COLOR] i = [COLOR=#800080]0 [/COLOR][COLOR=#0000ff]To [/COLOR][COLOR=#0000ff]ArrayLen[/COLOR](controls())-[COLOR=#800080]1[/COLOR]
[COLOR=#0000ff]  If [/COLOR][COLOR=#0000ff]ControlType[/COLOR](controls(i)) = [COLOR=#800000]"Button" [/COLOR][COLOR=#0000ff]Then[/COLOR]
[COLOR=#0000ff]   Control[/COLOR](controls(i)).Enabled = chkEnabled.Checked
[COLOR=#0000ff]  End [/COLOR][COLOR=#0000ff]If[/COLOR]
[COLOR=#0000ff] Next[/COLOR]
[COLOR=#0000ff]End Sub[/COLOR]
 
[COLOR=#0000ff]Sub [/COLOR]btnClear_Click
 TextBox1.Text = [COLOR=#800000]""[/COLOR]
[COLOR=#0000ff]End Sub[/COLOR]
Using the visual designer we've created the following form:
Picture1.jpg


All the 'regular buttons' are handled in Sub RegularButtons_Click.
This sub just adds the text of the sender button.
We enable and disable all the buttons using GetControls and ControlType.
The source code of this example is attached.

Another runtime keyword which is not covered here is CallSub.
CallSub calls a sub using a string as the sub name.
 

Attachments

  • RuntimeControls.sbp
    1.8 KB · Views: 830
Top