Correct usage of ComponentControls/ComponentMembers

Date:31 August 2007
Product/Release:Visual LANSA V10 and V11.3
Abstract:An explanation about the subtle differences between the two properties
Submitted By:LANSA Technical Support

When you want to perform the same action on several components, a common programming practice is to use a FOR loop on a collection of objects. In VL, there are two properties which will return a collection of objects that can be used for this purpose: The ComponentMembers and ComponentControls properties

These two properties are subtly different, and can cause confusion if not used correctly. This tip aims to clarify the differences between these properties and demonstrate how they can be used in your application

ComponentMembers:

ComponentMembers is a property that is only accessible in components which 'own' other components (as opposed to parentage, which is refers to visual hierarchy). In most cases #Com_Owner is the only component inside a form which actually owns other components unless the runtime Owner property has been specified for individual components/controls (additionally, only forms can be 'owners' of other controls).

When you access the ComponentMembers property of an object, you will get a collection of objects of type #PRIM_OBJT

ComponentControls:

ComponentControls is a property accessible in forms, panels, tab sheets and any control that has the ability to be the parent of other controls (i.e. other controls can be placed onto it). This is independent of Ownership since as noted above, most objects will still be owned by #Com_Owner. If you wanted to access all controls on a particular panel, you would use the ComponentControls property

When you access the ComponentControls property of an object, you will get a collection of objects of type #PRIM_CTRL

Example using ComponentControls:

The following code samples can be used to find all objects on a panel called #Panl_1, and change their visual style. Since #panl_1 is a parent to all objects placed on it you would use the ComponentControls property to access the objects on it. #Panl_1 is not the owner of these objects

Note that in the FOR loop, even though ComponentControls returns a collection of #Prim_Ctrl objects, #Current gets defined as a #Prim_Objt which has very limited properties. In order to have to have access to VisualStyle, and other properties of #Prim_Ctrl you must use object casting. In the code below we are confirming that #Current is an instance of type Prim_Ctrl before casting it as an object of this type (either as an Set_Ref or with RDMLX casting)

RDML Sample:

Define_Com Class(#Prim_Ctrl) Name(#Object) Reference(*Dynamic)
For Each(#Current) In(#Panl_1.ComponentControls)
If_Ref Com(#Current) Is(*INSTANCE_OF #Prim_Ctrl)
Set_Ref Com(#Object) To(*dynamic #Current)
Set Com(#Object) Visible(True)
Set Com(#Object) Visualstyle(#VS_Larem)
Endif
Endfor Set Com(#Object) Visualstyle(#VS_Larem)
Endif
Endfor

RDMLX Sample:

For Each(#Current) In(#Panl_1.ComponentControls)
Continue If(#Current *IsNot #Prim_Ctrl)
(#Current *As #Prim_ctrl).Visible := true
(#Current *As #Prim_ctrl).VisualStyle <= #VS_Norm
Endfor

Both of these samples can be easily expanded to perform much more useful functionality.