Member Classes Bring Flexibility The new VFP 8 feature often referred to as "Member Classes" is a set of new properties and new ways to define classes that can bring much more flexibility when working with certain controls.Need to define several pages in a pageframe with different properties and settings? No problem. How about better control of grid column headers? No problem. In Visual FoxPro, there are certain classes that have meaning only when they're in containers: for example, Pages and Headers can live only in PageFrame and Column objects. In versions before VFP 8, if we wanted to subclass these classes, we needed to manually add them using the AddObject method. But, there were problems with this approach. For example, this kept us from putting controls on a subclassed page in the Form Designer. However, VFP8 adds the MemberClass and MemberClassLibrary properties, as well as the HeaderClass and HeaderClassLibrary properties for the Column object. This lets us tell the containers what kind of controls they should be using when we change the properties that tell how many controls they contain. For example: *!* Create Header class library TEXT TO lcMembHeader NOSHOW DEFINE CLASS hdrMembClass as Header cSort = "ASCENDING"
PROCEDURE DblClick IF This.cSort = "ASCENDING" This.cSort = "DESCENDING" ELSE This.cSort = "ASCENDING" ENDIF
MESSAGEBOX(This.cSort) ENDPROC ENDDEFINE ENDTEXT
*!* Create Column class library, and pull from Header class library TEXT TO lcMembColumn NOSHOW DEFINE CLASS colMembClass AS Column HeaderClass = "hdrMembClass" HeaderClassLibrary = "membHeader.prg" ENDDEFINE ENDTEXT
*!* Create Grid class library, and pull from Column class library TEXT TO lcMembGrid NOSHOW DEFINE CLASS grdMembClass as Grid MemberClass = "colMembClass" MemberClassLibrary = "membColumn.prg" ENDDEFINE ENDTEXT
*!* Write the libraries to disk STRTOFILE(lcMembHeader, "membHeader.prg") STRTOFILE(lcMembColumn, "membColumn.prg") STRTOFILE(lcMembGrid, "membGrid.prg")
USE HOME(1) + "labels"
loform = CREATEOBJECT("Form") loForm.NewObject("Grid1", "grdMembClass", "membGrid.prg") WITH loForm.Grid1 .RecordSource = "labels" .RecordSourceType = 1 .Visible = .t. ENDWITH
loForm.Show(1)
With every release of VFP, there is something added that's so obvious, it tends to go in everyone's defaults. With VFP3, it was Label.AutoSize = .T. VFP5 added ComboBox.BoundTo = .T. Now that we're up to 8, I think we'll see something like the following: DEFINE CLASS pagRefresh as Page lRefresh = .T.
PROCEDURE Activate IF This.lRefresh This.Refresh() ENDIF ENDPROC ENDDEFINE
I added an lRefresh property to this class because of the possibility that you might not want a given page to refresh as soon as you switch to it. Once you've defined the classes, you can use them in the Form Designer by setting the properties at design time. When you make a design-time change to the MemberClass property, all of the controls will use the same class, even those already defined at that point. However, if you change the MemberClass and MemberClassLibrary properties at runtime, this will not affect existing controls. This opens up some interesting possibilities for dynamically switching between MemberClasses as you instantiate various objects at runtime. Listing 1 contains code to first change the MemberClass and MemberClassLibrary properties on a Pageframe in (simulated) design mode, then shows that at runtime the properties can be changed with just the new Pages being instantiated with the newly-defined MemberClass. For a more detailed example, please see the "Member Classes" Solution Sample that ships with VFP8. The easiest way to do this is to use the "Solution Samples" pane in the Task Pane, but you can still run SOLUTION.APP as always to get to the samples. Garrett Fitzgerald | & | | 
By: Garrett Fitzgerald
gfitzger@nyx.net | Fast Facts | | By changing the way you can define and work with member classes, Microsoft has given VFP developers tremendous flexibility in working with pageframes and grids. | |
Where to Define Member Classes
In all these examples, I've used classes defined in PRGs, instead of VCXs. With Pages, OptionButtons, and CommandButtons, you can define them either way. Headers and Columns, though, can be defined only in PRGs. |
| Listing 1: Code that illustrates dynamic switching of MemberClass property at runtime. | *!* Create a Page in a PRG TEXT TO lcPageClass NOSHOW DEFINE CLASS pagRed as Page BackColor = RGB(255, 0, 0) Caption = "Page" ENDDEFINE ENDTEXT STRTOFILE(lcPageClass, "membPagRed.prg") *!* Create a page in a VCX loPage = CREATEOBJECT("Page") loPage.BackColor = RGB(0, 0, 255) loPage.SaveAsClass("membPagBlue.vcx", "pagBlue") *!* Open the Form Designer and get an object reference *!* to the form. MODIFY FORM frmDesignTest NOWAIT ASELOBJ(laForm, 1) loForm = laForm(1) loForm.Themes = .F. && With the default of .T., we won't && see the colors loForm.AddObject("PageFrame1", "PageFrame") WITH loForm.PageFrame1 .MemberClassLibrary = "membPagRed.prg" .MemberClass = "pagRed" .PageCount = 5 .MemberClassLibrary = "membPagBlue.vcx" .MemberClass = "pagBlue" ENDWITH KEYBOARD "{CTRL+W}" *!* After this next line runs, we have blue pages, instead *!* of red pages. DO FORM frmDesignTest WAIT WINDOW TIMEOUT 5 *!* Now that we're at runtime, change the MemberClass *!* properties back, and increase the page count. WITH frmDesignTest.PageFrame1 .MemberClassLibrary = "membPagRed.prg" .MemberClass = "pagRed" .PageCount = 7 ENDWITH *!* We now have 5 blue pages and 2 red ones.
|
|