Sharing event handlers with Control Sets

Control Sets allow you to have a collection of controls that share a single set of event handlers. You create a control set by selecting a control and then changing the value for the Member Of property in the Inspector (located in the Control Set group on the Advanced tab of the Inspector).

To create a new Control Set for the selected control, choose New Control Set from the popup menu. This creates a Control Set with the name of the selected control.


You add other controls to the Control Set by clicking on them and selecting the Control Set name to add them to. When you do this you'll see the Index property get a value to indicate its position in the Control Set. This is how you can tell them apart.



If you only need to create controls dynamically at runtime, this can be done without the use of a Control Set.

You can also use a DesktopContainer as an alternative to Control Sets. They cannot be configured as a Control Set, although you can use Control Sets within a Container.

Once you have a Control Set you can refer to the individual controls by their index value. You will need to manually keep track of the total number of controls in your set for looping purposes. For example, if you have created a control set that consists of four TextFields, you can create a loop to update the text in each of the fields:

Var lastSetIndex As Integer = 3
For i As Integer = 0 To lastSetIndex
  MyTextFieldSet(i).Text = "Field " + i.ToString

Sharing event handlers

If you have multiple controls on the window that are part of a Control Set, the controls share their events. However, each event now has a new index parameter that you use to identify a specific control.

Controls Sets are a handy way to manage multiple controls that share similar functionality.

You can use the index parameter to iterate through the controls. For example, if you have a Control Set called MyCheckBox that consists of 4 Check Boxes, you could loop through them like this in a button's Pressed event to see which ones where checked:

For i As Integer = 0 To 3
 If MyCheckBox(i).Value Then
  MessageBox(MyCheckBox(i).Caption + " is selected")
 End If

Creating new controls in a Control Set via code

There may be situations where you can't build the entire interface ahead of time and need to create some or all of the interface elements programmatically. This can be done provided that the window already contains a control of the type you wish to create and that control belongs to a Control Set. In this case, the existing control is used as a template. For example, if you wish to create a Button via code, there must already be a Button on the window that you can “clone.” Remember that controls can be made invisible, so there is no need for your template control to be visible to the user. Once you have created a new instance of the control, you can then change any of its properties.

Suppose you need to clone a Button that is already in the window, named Button1.

To create a new Button control via code, do this:

  1. In the Inspector for the Button, select New Control Set from the Member Of popup menu in the Control Set group. When the new controls are created while the app is running, they become additional elements of this Control Set. In this example, you will create a new Button when the user clicks on the original Button.

  2. In the Pressed event of Button1, Var a variable of type DesktopButton, which is the base class for a Button. Assign the variable a reference to a new control using the New operator and use the name of the Control Set. This example shows a new Button being created using the Button1 Control Set. When the new control is created, it is moved to the right of the template control:

Var b As DesktopButton // this is the control class
b = New Button1 // create clone of the control on the layout
b.Caption = "Clone"
b.Left = Me.Left + Me.Width + 10 // reposition it
  1. Click the Run button. When the app launches, click the original button. This creates a new Button to the right of the original. If you click clone, you will create another clone to the right of the first two, and so on.

Since any new control you create in this manner shares the same event handler code as the template control, you may need to differentiate between them in your code. You use the index parameter of the control that is (passed in to the event handler to identify the control being used.

If your code needs to create different kinds of controls and store the reference to the new control in one variable, you can declare the variable as being of the type of object that all the possible controls you might be creating have in common (e.g, the super class or an interface). For example, if a variable can contain a reference to a new CheckBox, the variable can be declared as a DesktopUIControl because CheckBoxes inherit from the DesktopUIControl class. Keep in mind, however, since the variable is a DesktopUIControl, the properties specific to a DesktopCheckBox will not be accessible without casting.

Here is the preceding example using DesktopUIControl and casting:

Var c As DesktopUIControl
c = New Button1 // create clone
DesktopButton(c).Caption = "Clone"
DesktopButton(c).Left = Me.Left + Me.Width + 10

Removing controls from a Control Set via code

To remove a control that you added at run-time, you call the Close method for the control. This code can be used to remove the button created in the example above:


Remember, because Control Sets are not arrays if you remove a control in the middle of the Control Set you will get a hole in the index values. For example if you have four items in a Control Set they will initially have index values of 0, 1, 2, 3. If you remove index 2 then you will have three items in the Control Set with index values of 0, 1, 3. Index value 2 will be Nil.

Using Control Sets with menus

Control Sets can be used to allow a group of static menu items to share an event handler. To dynamically create menus it's better that you add to or remove items from menus at runtime using the AddMenu, AddMenuAt and RemoveMenuAt methods of the DesktopMenuItem class.

See also