Subclassing Controls

 <  Day Day Up  >  

The point of object-oriented programming is that what you do to a class is inherited by classes derived from it, and reflected in objects based on it.

You can begin to reap the benefits of object orientation in two minutes by subclassing the base form controls, and then using your subclassed controls on your forms. For example, let's say you create a label control of your own and use it on all of your forms. Shortly thereafter, your client decides to change the font with which labels are displayed on the screen. Instead of changing the FontName property of every label on every label on every screen, you change it in your label class, and the change instantly appears everywhere in your application. That's a powerful visual example of what inheritance can do for you.

Subclassing the FoxPro Screen Controls

To subclass the FoxPro screen controls, change to your project directory by typing CD ProjectDirectory and type the code shown in Listing 8.3. After each one pops up a designer, close the designer to save the class.

Listing 8.3. Code to Type in the Command Window to Create a Class Library Containing Subclasses of All of the FoxPro Controls
 CREATE CLASS MyLabel  OF FormControls AS Label CREATE CLASS MyText   OF FormControls AS TextBox CREATE CLASS MyEdit   OF FormControls AS EditBox CREATE CLASS MyButton OF FormControls AS CommandButton CREATE CLASS MyGroup  OF FormControls AS CommandGroup CREATE CLASS MyRadio  OF FormControls AS OptionGroup CREATE CLASS MyCheck  OF FormControls AS CheckBox CREATE CLASS MyCombo  OF FormControls AS ComboBox CREATE CLASS MyList   OF FormControls AS ListBox CREATE CLASS MySpin   OF FormControls AS Spinner CREATE CLASS MyGrid   OF FormControls AS Grid CREATE CLASS MyImage  OF FormControls AS Image CREATE CLASS MyTimer  OF FormControls AS Timer CREATE CLASS MyFrame  OF FormControls AS PageFrame CREATE CLASS MyLine   OF FormControls AS Line CREATE CLASS MyShape  OF FormControls AS Shape CREATE CLASS MyPanel  OF FormControls AS Container CREATE CLASS MyLink   OF FormControls AS HyperLink 

There are probably a few properties that you'll want to change before using them. For example, change the Enabled property of MyText , MyEdit , MyCheck , MyCombo , MyRadio , and MySpin to .F. . This allows us to display a form with data that users can't edit until they click on the Edit button. I also go into the Click event of the MyButton class and enter this:

 

 MessageBox ( "Not yet coded", 64, _VFP.Caption, 1000 ) 

This produces a message that reminds the programmer (that's me) that something isn't done.

Using Your Subclassed FoxPro Controls

Open a form, and then use View, Toolbars from the menu to display the Form Controls toolbar if it isn't already visible. Click on the View Class (the three little books) icon and click on Add (which is very unintuitive, but which actually means "add a new class library to this list") and select FormControls.VCX from the resulting dialog. Voil  , you've got classes! If you use these instead of FoxPro's base classes, you're ready to reap the benefits of OOP with just two minutes' work.

But the best way to begin using your new subclassed controls in FoxPro is to select Tools, Options, Field Mapping, and then enter the name of a control and the FormControls.vcx class library for each of the data types you're likely to use in your tables. After you've done this (be sure to click Apply for each selection), you can open the Data Environment of a form, add a table or cursor, click on the word Fields at the top of the cursor icon and drag and drop it on the screen, and you're instantly using your controls, both a label and the appropriate control based on the data type. It's the biggest bang for the buck in FoxPro.

If you want to do something to your controls, say enable or disable them, you can use FOR EACH Ctrl in THISFORM.CONTROLS...ENDFOR to iterate through them. Earlier, we saw how that's done. But usually a little more is required.

For example, I often start with all input controls disabled, enable them when the user selects Add or Edit, and then disable them again when they click Save or Cancel. To do this, I add a form class property called EditableFields , and populate with the names of the controls that should be enabled or disabled, as shown in Listing 8.4.

Listing 8.4. Providing a List of Editable Field Classes in Visual FoxPro
 DEFINE CLASS MyBaseForm AS Form ... EditableFields = [MyTextMyEditMyCheckMyComboMyRadioMySpin] 

You can also create your form class in the Class Designer, use the Class, Add Property menu selection to add the property, and then open the Properties sheet for the class and type in the "EditableFields = " string shown in Listing 8.4. Then, you can enable them in the form class method called EnableFields as shown in Listing 8.5.

Listing 8.5. The EnableFields Form Class Method
 PARAMETERS OnOff FOR EACH Ctrl in THISFORM.Controls     IF UPPER(Ctrl.Class) $ UPPER(THISFORM.EditableFields)         Ctrl.Enabled = OnOff     ENDIF ENDFOR 

To use this method, include the line THISFORM.EnableFields(.T.) in your cmdAdd and cmdEdit Click event code, and include the line THISFORM.EnableFields(.F.) in your cmdSave and cmdCancel Click event code. Better still, add these lines in the form's Save and Cancel methods that are called by the Edit, Add, Save, and Cancel buttons ' Click event code.

Subclassing the Screen Controls in Visual Basic .NET

Subclassing the form controls in Visual Basic .NET is as easy as pie, although not as easy as in FoxPro. Visual Basic doesn't have Visual Class Libraries (VCX files). Instead, you build a class file and declare each of the class names you want to use, following each Public Class statement with an Inherits statement that specifies the base class. It's almost too easy. However, to compensate for that, adding behavior to a class is harder and less obvious.

Let's say you want to create a half- dozen input classes and change the text box background color when it has the focus. In FoxPro you just drag the controls onto the Class Designer, set some properties in the Properties sheet, and then double-click and override the GotFocus and LostFocus events.

In Visual Basic .NET, you can't set properties visually in a class designer; you have to add a New method (a "constructor", like FoxPro's Init() method), and then add property assignments in the New method after calling the MyBase.New() method. Then, if there are base class events where you want to do something, you have to write an "event handler" and add a Handles clause to tie it to the original event. Note that the equivalents of GotFocus and LostFocus are called Enter and Leave respectively in .NET.

The code shown in Listing 8.6 goes in the Class1 file that is created automatically when you select File, New, Project from the IDE menu and select Class as the project type. Name the project MyFormControls and change the name of Class1.vb to MyControls.vb .

TIP

You'll have to add references to System.Windows.Forms and to System.Drawing to the class library project, and also add the two Imports statements at the top of the class listing.


Listing 8.6. Subclassing the Base Form Control Classes in Visual Basic .NET
 Imports System.Windows.Forms Imports System.Drawing Public Class MyText     Inherits TextBox     Public Sub New()         MyBase.New()         Text = ""         Enabled = False     End Sub     Public Sub EnterHandler( )       ByVal o As Object, _       ByVal e As EventArgs) _      Handles MyBase.Enter         BackColor = BackColor.Blue         ForeColor = ForeColor.White     End Sub     Public Sub LeaveHandler( _       ByVal o As Object, _       ByVal e As EventArgs) _      Handles MyBase.Leave         BackColor = BackColor.White         ForeColor = ForeColor.Black     End Sub End Class Public Class MyCombo     Inherits ComboBox     Public Sub New()         MyBase.New()         Text = ""         Enabled = False     End Sub     Public Sub EnterHandler( _       ByVal o As Object, _       ByVal e As EventArgs) _      Handles MyBase.Enter         BackColor = BackColor.Blue         ForeColor = ForeColor.White     End Sub     Public Sub LeaveHandler( _       ByVal o As Object, _       ByVal e As EventArgs) _      Handles MyBase.Leave         BackColor = BackColor.White         ForeColor = ForeColor.Black     End Sub End Class Public Class MyCheck     Inherits CheckBox     Public Sub New()         MyBase.New()         Enabled = False     End Sub End Class Public Class MyLabel     Inherits Label     Public Sub New()         MyBase.New()         Text = "Lbl"     End Sub End Class Public Class MyRightAlignedLabel     Inherits MyLabel     Public Sub New()         MyBase.New()         TextAlign = ContentAlignment.MiddleRight     End Sub End Class Public Class MyRadio     Inherits RadioButton     Public Sub New()         MyBase.New()         Enabled = False     End Sub End Class 

Using Your Subclassed .NET Controls

To use these controls, click on the User Controls toolbox heading, and then right-click and select Add/Remove Items. When the dialog appears, use Browse to find and click on [VSProjDir] \MyFormControls\bin\MyFormControls.DLL . All of the controls you just created will appear in your User Controls toolbox. You use them, rather than the base control classes, on your forms. Now, just as in FoxPro, if you change the FontName in the subclassed MyLabel class, it changes in all of your forms.

Enabling/Disabling the Controls on a Form

In Listing 8.7, you have an Input procedure that can be called both from here and from click events such as Add and Edit . I look for any control whose name is in the form's list of input fields, and apply the Enabled = True/False logic only to those controls.

Listing 8.7. Enabling and Disabling All Form Input Controls in Visual Basic .NET
 Dim UserControls As String = "MYTEXTMYCOMBOMYRADIOMYSPINMYCHECK" Private Sub cmdEnableDisable_Click( _    ByVal sender As System.Object, _    ByVal e As System.EventArgs) _   Handles cmdEnableDisable.Click     Inputs(Button1.Text = "Enable")     Button1.Text = IIf(Button1.Text = "Enable", "Disable", "Enable") End Sub Public Sub Inputs(ByVal OnOff As Boolean)     Dim CtrlType As String     Dim LastPeriod As Integer     Dim Ctrl As Control     For Each Ctrl In Controls     LastPeriod = Ctrl.GetType.ToString.ToUpper.LastIndexOf(".") + 1     CtrlType = Ctrl.GetType.ToString.ToUpper.Substring(LastPeriod)     If UserControls.IndexOf(CtrlType) > 0 Then Ctrl.Enabled = OnOff     Next End Sub 

I use the fact that the name of a control's base class is located after the last period in the GetType return value. I convert both search and target to uppercase before looking for the control's base class name in the User Controls string. The initial "" character is not optional, by the way; otherwise , MYTEXT is found at location zero (thanks, Bill).

The parameter ( Button1.Text = "Enable" ) uses a shorthand method of coding that sets the value of the Input() call's single parameter to True if the text property of the button is the string "Enable" , and to False if it says "Disable" (or anything else, for that matter). The last line changes the caption of the button itself.

 <  Day Day Up  >  


Visual Fox Pro to Visual Basic.NET
Visual FoxPro to Visual Basic .NET
ISBN: 0672326493
EAN: 2147483647
Year: 2004
Pages: 130
Authors: Les Pinter

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net