Desktop Control Sets
From Xojo Documentation
|You are currently browsing the old Xojo documentation site. Please visit the new Xojo documentation site!|
|Control Sets are no longer needed because you can now create controls at runtime and add them to the layout for all project types. It is suggested that you do that rather than use Control Sets.|
Control Sets serve two purposes. One is to allow you to have a collection of controls that share a single set of event handlers. The other is to create controls dynamically while your app is running. In both cases, 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.
|Control Sets were previously known as Control Arrays (in 2012 and earlier). They were renamed because they are not arrays and really don’t have anything to do with arrays.|
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:
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:
If MyCheckBox(i).Value Then
MessageBox(MyCheckBox(i).Caption + " is selected")
Dynamic Controls / Adding Controls at Run-Time
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:
- 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.
- 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:
b = New Button1 // create clone of the control on the layout
b.Caption = "Clone"
b.Left = Me.Left + Me.Width + 10 // reposition it
- 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 Check Box, the variable can be declared as a DesktopUIControl because Check Boxes 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:
c = New Button1 // create clone
DesktopButton(c).Caption = "Clone"
DesktopButton(c).Left = Me.Left + Me.Width + 10
Removing Controls at Run-Time
To remove a control that you added at run-time, you call the Close method for the control. This code can be used to add a new Button to a control set:
NewButton = New Button1 // create clone
NewButton.Caption = "Clone"
NewButton.Left = Me.Left + Me.Width + 10
Elsewhere, you can use this code to remove the added DesktopButton:
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.
Control Sets with Menus
You can add or remove items to menus at run-time using the Append, Insert and Remove methods of the MenuItem class. Using this technique is preferred over a Menu Control Set, which remains available as an option.