Example 3: Collection to Manage Forms

This example shows a form which manages its child forms using a keyed collection:

When you click on the Create a Form B button, a new instance of Form B is created and added to the collection. You can use the other two buttons to move the forms right or left.

Define the Collection

The collection to store child forms is defined like this:

 

Define_Com Class(#Prim_Kcol<#FormB #Std_Num>) Name(#FormBs)

 

Add Items to the Collection

The code to create a new form B in the collection is contained in the Click event of the Create a Form B button:

 

Change Field(#LISTCOUNT) To('#FormBs.ItemCount + 1')

Invoke Method(#FormBs<#listcount>.showform)

In the above note that:

Work with the Collection Items

The click events of the two buttons to move the child forms to right and left use two different ways of working with items in a collection.

The click event of the Move all Form Bs Right button invokes a MoveRight method of Form B for all forms in the collection:

Invoke Method(#formBs<>.MoveRight)

To work with all items in the collection specify a blank key for the collection:

#CollectionName<>

The click event of the Move all Form Bs Left uses a For/EndFor loop to iterate through the items in the collection and to move them to the left:

For Each(#Current) In(#FormBs)

Change Field(#NEW_LEFT) To('#Current.Left - 5')

Set Com(#Current) Left(#New_Left)

Endfor

Also see

Multi-Form Applications

Source Code for Collection Example 3

Form A

Function Options(*DIRECT)

Begin_Com Role(*EXTENDS #PRIM_FORM) Caption('Form A') Clientheight(108) Clientwidth(336) Height(135) Layoutmanager(#GDLM_1) Left(286) Top(124) Width(344)

* Using a Keyed Collection (PRIM_KCOL) to handle a multi-form application.

* Define the keyed collection to be used to store the child forms.

* The collection is named #FormBs and it collects #FormBs.

* It is keyed by #Std_Num ie: a packed (7,0) number.

Define_Com Class(#Prim_Kcol<#FormB #Std_Num>) Name(#FormBs)

* Define the form.

* CreateFormBtn will create an instance of FormB

* MoveRightBtn will move all the child FormBs to the right

* MoveLeftBtn will move all the child FormBs to the left

Define_Com Class(#PRIM_PHBN) Name(#CreateFormBtn) Caption('Create a Form B') Displayposition(1) Left(30) Parent(#COM_OWNER) Tabposition(1) Top(29) Width(109)

Define_Com Class(#PRIM_PHBN) Name(#MoveRightBtn) Caption('Move all Form Bs Right') Displayposition(2) Left(139) Parent(#COM_OWNER) Tabposition(2) Top(29) Width(166)

Define_Com Class(#PRIM_PHBN) Name(#MoveLeftBtn) Caption('Move all Form Bs Left') Displayposition(3) Left(139) Parent(#COM_OWNER) Tabposition(3) Top(54) Width(166)

* Grid layout manager to position the buttons

Define_Com Class(#PRIM_GDLM) Name(#GDLM_1)

Define_Com Class(#PRIM_GDLI) Name(#GDLI_1) Manage(#CreateFormBtn) Parent(#GDLM_1)

Define_Com Class(#PRIM_GDLI) Name(#GDLI_2) Left(2) Manage(#MoveRightBtn) Parent(#GDLM_1)

Define_Com Class(#PRIM_GDLI) Name(#GDLI_4) Left(2) Manage(#MoveLeftBtn) Parent(#GDLM_1) Top(2)

* Definition of child form (FormB)

Define_Com Class(#FORMB) Name(#FORMB) Componentversion(1)

* Fields used to position the child forms (FormB)

Define Field(#NEW_TOP) Reffld(#STD_NUM)

Define Field(#NEW_LEFT) Reffld(#STD_NUM)

Evtroutine Handling(#CreateFormBtn.Click)

* Use the keyed collection property ItemCount to get the next slot in the collection

Change Field(#LISTCOUNT) To('#FormBs.ItemCount + 1')

* Show the form. When the form is shown, it is created and added to the collection

Invoke Method(#FormBs<#listcount>.showform)

* Adjust the form's position from the left and top

Change Field(#NEW_LEFT) To('#FORMBS<#listcount>.Left + (#listcount * 30)')

Change Field(#NEW_TOP) To('#FORMBS<#listcount>.top + (#listcount * 30)')

Set Com(#formBs<#listcount>) Left(#NEW_LEFT) Top(#NEW_TOP)

Endroutine

Evtroutine Handling(#MoveRightBtn.Click)

* Invoke the MoveRight method in FormB to move all forms in the collection to the right

Invoke Method(#formBs<>.MoveRight)

Endroutine

Evtroutine Handling(#MoveLeftBtn.Click)

* Use a For/EndFor loop to iterate through all the forms in the collection and to move them to the left

For Each(#Current) In(#FormBs)

Change Field(#NEW_LEFT) To('#Current.Left - 5')

Set Com(#Current) Left(#New_Left)

Endfor

Endroutine

End_Com

Form B

Function Options(*DIRECT)

Begin_Com Role(*EXTENDS #PRIM_FORM) Caption('Form B') Clientheight(103) Clientwidth(180) Formstyle(StayOnTopChild) Height(130) Layoutmanager(#ATLM_1) Left(591) Top(136) Width(188)

* Define the child FormB used by FormA

* Define a label

Define_Com Class(#PRIM_LABL) Name(#LABL_1) Alignment(Center) Caption('Form B ') Displayposition(1) Height(103) Left(0) Parent(#COM_OWNER) Tabposition(1) Tabstop(False) Top(0) Verticalalignment(Center) Width(180)

* Center the label on the form using an attachment layout

Define_Com Class(#PRIM_ATLM) Name(#ATLM_1)

Define_Com Class(#PRIM_ATLI) Name(#ATLI_1) Attachment(Center) Manage(#LABL_1) Parent(#ATLM_1)

* Define a field to position the form

Define Field(#NEW_RIGHT) Reffld(#STD_NUM)

* Method to move the form to the right by incrementing the value of its Left property

Mthroutine Name(MoveRight) Help('This method moves the form to the right.')

Change Field(#NEW_RIGHT) To('#COM_OWNER.LEFT + 5')

Set Com(#com_owner) Left(#NEW_RIGHT)

Endroutine

End_Com

When you create a new form and specify an ancestor for it, the inheriting form will look and behave exactly like its ancestor form.