Depending on your application and development environment, it can be useful to extend and work with .NET forms and control containers using ABL-derived .NET classes. The Visual Designer in Progress Developer Studio for OpenEdge allows you to visually design .NET forms and control containers from a palette of .NET controls (see OpenEdgeInstalled .NET Controls). It then generates ABL code for these forms and control containers as ABL-derived .NET form and control container objects. For more information on the Visual Designer, see OpenEdge Getting Started: Introducing the Progress Developer Studio for OpenEdge Visual Designer.
You can also write your own ABL-derived .NET classes to extend .NET forms and control containers using a similar design pattern. In general, using this design pattern, you interact with inherited protected and public members and add additional public members to these extended forms and control containers, as necessary, to allow your application to interact with application-specific elements of these objects. Otherwise, you can interact with these ABL-derived objects exactly like their base .NET object types using the inherited public members. (For more information on defining and using ABL-derived .NET classes, see DefiningABL-extended .NET objects). Using the same basic design pattern, you can implement extended versions of the basic .NET control and control container types:
Non-modal forms — Windows that, once displayed, the user can enter, leave, and close in any order and manner that the user chooses according to the application design.
Modal dialog boxes — Windows that, once displayed, the user must enter and close before entering any other window in the application.
MDI forms — A non-modal window that contains other (child) non-modal windows. The MDI parent form provides a client area in which the user can display and manage child non-modal windows according to the application design. The user thus views the entire MDI form as a kind of desktop within a desktop.
Control containers — Any of several .NET classes that provide a standard means of containing and managing other .NET controls as a group. The key feature of these control containers is that they can be contained and managed by a .NET form as members of a control collection like any individual control, and they can typically contain other control containers as well as individual controls within their own control collection. OpenEdge provides enhanced support for a special class of control container, a user control, that you can define by using the ABL User Control option on the New > File menu in Progress Developer Studio for OpenEdge. This option creates a new ABL class that inherits the Progress.Windows.UserControl class (see OpenEdge .NET form and control objects). Once you define it, you can use the extended user control as a design element in the Visual Designer, like any .NET control, by adding it to the Toolbox and dragging it onto other forms and user controls that you design.
Inherited controls — You can extend any .NET control class that is not defined as sealed (FINAL). For example, you might define a custom Microsoft Label control that conforms to certain style conventions or that contains standard initial text, or you might define a custom TreeView control that always supports an initial node arrangement that is standard for all TreeView instances in an application. OpenEdge provides enhanced support for extending .NET controls by using the ABL Inherited Control option on the New > File menu in Progress Developer Studio for OpenEdge. This option creates a new ABL class that inherits a .NET control class that you specify. Once you define it, you can use the inherited control as a design element in the Visual Designer, like any .NET control, by adding it to the Toolbox and dragging it onto the forms and user controls that you design.
Note: All forms that derive from System.Windows.Forms.Form, themselves, represent a special type of control container that can contain any other type of control or control container object except another form.
This design pattern for ABL-derived forms and control containers generally includes the following elements (listed in no particular order):
A single default PUBLIC constructor, which calls a PRIVATE InitializeComponent( ) method and subscribes to any events that are handled by the ABL class itself
The PRIVATE IntializeComponent( ) method, which creates and initializes the ABL-derived .NET container and all the controls and other control containers that it adds to its control collection
Any event handlers for events that are handled internally by the ABL class
A destructor to delete any non-class-based objects created by the ABL class, any class-based objects you do not want to leave for ABL and .NET garbage collection to clean up, and to otherwise clean up resources maintained by instances of the class
Note: For resources that you create only for use within the scope of a particular method (or property accessor), you generally clean up these resources within the scope of that particular method (or property).
Any additional PUBLIC ABL properties and methods necessary to make the extended .NET object work in your application
For forms, in addition to the previous listed elements:
If you are implementing the main form for your application, you typically provide a PUBLIC ABL method to execute a .NET WAIT-FOR statement that specifies THIS-OBJECT as the main form.
Note: For any number of non-modal .NET forms (including MDI forms) and ABL windows, you can only have one .NET WAIT-FOR statement active at a time in an ABL session. Therefore, if you do have a main form in your application, you typically use the WAIT-FOR statement that specifies a main form. If there is no main form, you have no need to encapsulate a call to the WAIT-FOR statement in a PUBLIC method, because you can execute the WAIT-FOR statement directly in the main line of your application without specifying a particular form as the main form.
If you are implementing a modal dialog box that has an owning form, especially one that can be displayed from different owning forms, you might provide a PUBLIC ABL method to execute a .NET WAIT-FOR statement that calls the ShowDialog( ) method on THIS-OBJECT, taking a reference to its owning form as an INPUT parameter.
Caution: If you display a modal dialog box, you must call Dispose( ) on the form after your application is done with it. For more information, see Blockingon modal dialog boxes. If the form contains any ABL-derived controls or control containers, such as user controls, those controls are also not garbage collected until you call Dispose( ), which enables them for garbage collection as long as there are no other references to them in the ABL session.
The following sections use these elements to implement sample ABL-derived versions of the basic types of .NET form and control container classes: