Created On:  17 July 2012


A Windows Form application displays a main form.  This main form contains many different overlaying Panel controls on which there are a number of different textBox controls.
Depending on some condition in that form one of these Panel controls is to be made active while the others are made invisible.

What is happening is that the later panels that have been added are not being made visible even though the following statement is executed:

set Panelx::Visible to TRUE

What am I doing wrong?


What may be happening is that your second panel has been created such that it is a child of the first panel instead of the form itself. That would make panel1 the container and if it was invisible then panel2 would also be invisible.

If you are creating the two panels using the Winform Designer then make sure that the top left hand corner of panel2 does not lie within panel1 or it will generate the code-behind such that panel1 is the container for panel2.

If you look in the .designer.cbl file for the form and see code like the following it means that panel1 is the container for panel2

*> panel1
invoke panel1::Controls::Add(panel2)

You should instead see:
*> Form1
set self::ClientSize to new System.Drawing.Size( 384 362)
invoke self::Controls::Add(panel1)
invoke self::Controls::Add(panel2)

It may be better to look at using either a tabControl, where you set up a different TabPage for each set of input fields or create a User Control for each of the panels and add the required user control dynamically depending on the option selected.

The later would probably be the easiest to maintain.

There is an attached example of how to do this with User Controls.

This sample has a simple form with two radio buttons and a panel.

Depending on which radio button is selected, the appropriate User Control will be added to the panel.

Pressing the getData button at the bottom will get all the text fields from both user controls using properties and format a multiline textbox using the data.

The main form program looks like this:

*                                     TESTUSERPANEL                                     *
*                                                                                       *
* This example program demonstrates how User Controls can be used to overlay an area of *
* a form in order to provide for custom data entry fields based on certain other condi- *
* tions that are met on the form. This method can be used instead of overlaying panel   *
* controls which become very cumbersome to design and use because the Forms Painter does*
* not work very well when designing multiple overlapping panel controls on the same     *
* form.                                                                                 *
*                                                                                       *
* This example has two user controls, UserControl1 and UserControl2 which each contain  *
* multiple text fields. Since these User Controls are actually designed separately from *
* the main form you do not have the problem of overlaying them at design time. The main *
* form contains two radio buttons. If the first one is checked then the UserControl1    *
* will be added to a panel on the main form. If the second one is checked then the User *
* Control2 will be added to the panel and UserControl1 will be removed.                 *
*                                                                                       *
* A set of properties is defined in each User Control to allow easy access to the data  *
* in each of the textboxes via main form. When you press the getData button on the main *
* it will read the content of textboxes on both controls and format and display the     *
* values in a multiline textbox on the main form.                                       *

class-id testuserpanel.Form1 is partial
   inherits type System.Windows.Forms.Form.
working-storage section.
01 myusercontrol1 type testuserpanel.UserControl1 value new testuserpanel.UserControl1.
01 myusercontrol2 type testuserpanel.UserControl2 value new testuserpanel.UserControl2.
method-id NEW.
procedure division.
    invoke self::InitializeComponent
    invoke panel1::Controls::Add(myusercontrol1) *> default setting
end method.
method-id radioButton1_CheckedChanged final private.
procedure division using by value sender as object e as type System.EventArgs.
    if radioButton1::Checked
       invoke panel1::Controls::Clear
       invoke panel1::Controls::Add(myusercontrol1)
end method.
method-id radioButton2_CheckedChanged final private.
procedure division using by value sender as object e as type System.EventArgs.
    if radioButton2::Checked
       invoke panel1::Controls::Clear
       invoke panel1::Controls::Add(myusercontrol2)
end method.
method-id button1_Click final private.
01 mydata type StringBuilder.
procedure division using by value sender as object e as type System.EventArgs.
    set mydata to new StringBuilder
    invoke mydata::AppendLine(myusercontrol1::Contact)
    invoke mydata::AppendLine(myusercontrol1::Company)
    invoke mydata::AppendLine(myusercontrol1::Phone)
    invoke mydata::AppendLine(myusercontrol2::Address1)
    invoke mydata::AppendLine(myusercontrol2::City)
    invoke mydata::AppendLine(myusercontrol2::State)
    invoke mydata::AppendLine(myusercontrol2::Zip)
    set textBox1::Text to mydata::ToString
end method.
end class.