Try OpenEdge Now
skip to main content
GUI for .NET Programming
Creating and Using Forms and Controls : Creating custom .NET forms and controls : Sample ABL-derived .NET user control
 

Sample ABL-derived .NET user control

SampleUserControl is a sample ABL-derived user control class based on Progress.Windows.UserControl. Progress.Windows.UserControl inherits from the .NET System.Windows.Forms.UserControl class and allows you to define a control container that functions as a user-defined .NET control (user control). In an ABL-derived user control, you can contain a set of other ABL-derived user controls, .NET controls, and control containers that you might want to function together as a single control for use in several different applications.
Note: In Progress Developer Studio for OpenEdge, you can create ABL-derived user controls for reuse as new design components in Visual Designer. You can initiate creation of a new user control by clicking on File > New > ABL User Control.
SampleUserControl initializes a user control much like an ABL-derived form might initialize itself (see the previous sample ABL-derived .NET classes, for example, as described in Sample ABL-derived .NET non-modal form). In this case, the user control contains two .NET controls:
*A password field implemented by an Advanced UI Control (Infragistics.Win.UltraWinEditors.UltraTextEditor)
*A Login button implemented by another Advanced UI Control (Infragistics.Win.Misc.UltraButton)
The sample ABL class, UserControlForm, displays this control container in a non-modal form, and the sample UserControlFormDriver.p procedure displays the form, as in the following figure.
Figure 9. User control displayed for UserControlForm.cls
In the user control, you can type a masked password string in a text box and you can click the Login button, but there is no other behavior implemented for this control. For information on locating and running these samples, see Example procedures.
Note that in this example, UserControlForm is the only form class where SampleUserControl is used. Typically, you design a single ABL-derived user control for use in multiple forms or applications. For example, a single login user control might be used in any number of application modules where a user might be required to enter security credentials.
This is the initial section of code for the ABL SampleUserControl class, where the class private data and public members are defined.
USING Infragistics.Win.UltraWinEditors.* FROM ASSEMBLY.
USING Infragistics.Win.Misc.* FROM ASSEMBLY.

CLASS SampleUserControl INHERITS Progress.Windows.UserControl:

  /* Class private data */
  DEFINE PRIVATE VARIABLE rPasswordEditor AS CLASS UltraTextEditor NO-UNDO.
  DEFINE PRIVATE VARIABLE rLoginButton AS CLASS UltraButton NO-UNDO.
 
  /* Class public members */
  DEFINE PUBLIC PROPERTY PasswordEntry AS CLASS UltraTextEditor NO-UNDO
    GET.
    PRIVATE SET.

  DEFINE PUBLIC PROPERTY LoginButton AS CLASS UltraButton NO-UNDO
    GET.
    PRIVATE SET.

  CONSTRUCTOR PUBLIC SampleUserControl( ):
    InitializeComponent( ).
  END CONSTRUCTOR.
The rPasswordEditor and rLoginButton variables define PRIVATE object references to the control objects contained by the user control. The read-only PasswordEntry and LoginButton properties provide PUBLIC object references to these control objects for use by the form that contains the user control. This sample does not use these properties except to assign them references to their associated control objects.
Note: Because ABL does not allow you to define events for ABL classes, you cannot define events for an ABL-derived .NET class, including a user control. A form class that contains a user control and wants to respond to events on the controls it contains has two options. It must either subscribe event handlers directly to events on the public controls contained by the user control or the user control, itself, can subscribe proxy event handlers to its contained control events that call the real event handlers defined in the form class. For more information on creating and using proxy event handlers, see Handling events on controls contained by ABL-derived .NETclasses.
As is typical for ABL container classes, the constructor invokes an InitializeComponent( ) method, which instantiates and initializes the user control.
The InitializeComponent( ) method follows, which completes the SampleUserControl class.
  METHOD PRIVATE VOID InitializeComponent( ):

    /* Initializes extended user control container class with
       controls and initializes public properties to access them */
    rPasswordEditor = NEW UltraTextEditor( ).
    PasswordEntry = rPasswordEditor.
    rLoginButton = NEW UltraButton( ).
    LoginButton = rLoginButton.
    
    CAST(rPasswordEditor,
       System.ComponentModel.ISupportInitialize):BeginInit( ).
    THIS-OBJECT:SuspendLayout( ).

    /* Set properties */
    rPasswordEditor:Location = NEW System.Drawing.Point( 20, 0 ).
    rPasswordEditor:Size = NEW System.Drawing.Size( 150, 21 ).
    rPasswordEditor:TabIndex = 0.
    rPasswordEditor:Text = "".
    rPasswordEditor:PasswordChar = "*".
    
    rLoginButton:Text = "Login".
    rLoginButton:Location = NEW System.Drawing.Point( 20, 31 ).
    rLoginButton:Size = NEW System.Drawing.Size( 75, 30 ).
    rPasswordEditor:TabIndex = 1.

    THIS-OBJECT:AutoScaleDimensions = NEW System.Drawing.SizeF( 6, 13 ).
    THIS-OBJECT:AutoScaleMode = System.Windows.Forms.AutoScaleMode:Font.

    /* Add controls to form */
    THIS-OBJECT:Controls:Add( rPasswordEditor ).
    THIS-OBJECT:Controls:Add( rLoginButton ).
    THIS-OBJECT:ClientSize = NEW System.Drawing.Size( 200, 200 ).

    CAST(rPasswordEditor,
       System.ComponentModel.ISupportInitialize):EndInit( ).
    THIS-OBJECT:ResumeLayout( FALSE ).
    THIS-OBJECT:PerformLayout( ).

  END METHOD.

END CLASS.
The general initialization process is exactly like initializing a .NET form. It starts by initializing its two control objects contained by the user control (rPasswordEditor and rLoginButton) and setting public properties for them. The Location property settings for each control are relative to the client area of the user control. When the user control is added to a form, its Location property is then specified relative to the client area of the form, thus positioning all constituent controls of the user control on the form as a unit. The AutoScale* properties allow the user control and its controls to scale with its form, according to the system font size.
Note: The CAST function enables access to the explicit interface members, BeginInit( ) and EndInit( ), which are required to initialize the UltraTextEditor control (see Accessing members of .NET interfaces).
This is the code for the sample ABL-derived client form class of SampleUserControl, UserControlForm.
CLASS UserControlForm INHERITS Progress.Windows.Form:

  /* Class private data */
  DEFINE PRIVATE VARIABLE demoControl AS CLASS SampleUserControl NO-UNDO.

  /* Class public members */
  METHOD PUBLIC VOID DoWait( ):
    WAIT-FOR System.Windows.Forms.Application:Run( THIS-OBJECT ).
  END METHOD.

  CONSTRUCTOR UserControlForm( ):
    InitializeComponents( ).
  END CONSTRUCTOR.

  METHOD PRIVATE VOID InitializeComponents( ):

    /* Creates base form class and all components */
    demoControl = NEW SampleUserControl( ).

    THIS-OBJECT:SuspendLayout( ).

    /* Set properties */
    THIS-OBJECT:AutoScaleDimensions = NEW System.Drawing.SizeF(6, 13).
    THIS-OBJECT:ClientSize = NEW System.Drawing.Size(290, 260).
    demoControl:Location = NEW System.Drawing.Point(0, 20).

    /* Add controls to form */
    THIS-OBJECT:Controls:Add( demoControl ).
    
THIS-OBJECT:ResumeLayout( FALSE ).

  END METHOD.

END CLASS.
With the SampleUserControl class, form initialization in the ABL UserControlForm class becomes much simpler than for the previously described ABL-derived non-modal form classes (for example, CurrentTimeForm described in Sample ABL-derived .NET non-modal form). In this case, there is one object reference (demoControl) for all the controls on the form. Control initialization is a matter of using this one object reference to position the control container in the client area of the form by setting its Location property and to add the control container to the form's control collection. UserControlForm could also use the other public properties of SampleUserControl to subscribe event handlers to its control events, if the application required it.