Level Extreme platform
Subscription
Corporate profile
Products & Services
Support
Legal
Français
Who's in control
Message
From
25/08/1999 18:52:21
 
General information
Forum:
Visual FoxPro
Category:
Object Oriented Programming
Miscellaneous
Thread ID:
00257679
Message ID:
00257688
Views:
28
>I just started learning VFP about 2 months ago, as well as working in an OOP environment so I am a little unclear on how to notify objects in a series of containers about an event.
>
>I pretty much understand the concept of an object is in control of it's own environment and nobody should play with it's stuff. I think Dragan said it best in another post today 'Your controls should be grown up independent controls, capable of taking care of themselves.'
>
>Today I was working on some methods to resize controls when the form is resized. So I built an array of the forms controls that could be resized in the forms init. Thinking that I would also do something similar for each container that might happen to be on a form. At init every object builds its own array of it's child objects. Then just add a DoResize method to everything and let each object take care of itself.
>
>I of course realized that didn't work when I hit the pageframe. It's children are containers that can't be subclassed. Bummer. And I feel that is probably not the best OO way to do it.
>
>So I started to think about taking a bottom up approach. Have each child tell the parent it exists, if the parent can't deal with it just go to the next parent up the line. Problem is, at init, the parent doesn't exist yet.
>
>So it seems if you want the most top-level parent to inform all of it's contained objects that something happened, that parent is going to have look for all children.
>
>So is drilling down the way to do it, or is there another way?

My base form class has a recursove method called RunAll that might help you:
lPara tcMethod, toContainer, tcClass

LOCAL lcMethod, loContainer, loControl, loPage, loColumn, lcSetExact

IF TYPE('tcMethod') <> "C"
	RETURN .F.
ELSE
	lcMethod = tcMethod
ENDIF

* If no container object was passed in, assume that
* we are running all methods in THIS
IF TYPE("toContainer.Name") <> "C"
	loContainer = THIS
ELSE
	loContainer = toContainer
ENDIF

* set exact on to make sure pages weren't mistaken for pageframes and vice-versa
lcSetExact = SET('EXACT')
SET EXACT ON

* this method only works for container-type classes
IF !INLIST(LOWER(loContainer.BaseClass), "form","container","pageframe","page","grid","column")
	RETURN .F.
ENDIF

DO CASE
	CASE INLIST(LOWER(loContainer.BaseClass),"form","container","page","column")
		FOR EACH loControl IN loContainer.Controls
			* Does the control have the method passed in?
			IF PEMSTATUS(loControl, lcMethod, 5)
				=EVAL("loControl." + lcMethod + "()")
			ENDIF
			* if the control is a container itself, recurse back into this method to drill down into its controls
			IF INLIST(LOWER(loControl.BaseClass), "form","container","pageframe","page","grid","column")
				THIS.RunAll(lcMethod, loControl)
			ENDIF
		ENDFOR

	* I am really doing the same thing for all three of these container types,
	* but the controls collection is called something different in each of them,
	* so I had to separate them out,
	CASE LOWER(loContainer.BaseClass) = "pageframe"
		* For pageframes, iterate through the pages collection
		FOR EACH loPage IN loContainer.Pages
			IF PEMSTATUS(loPage, lcMethod, 5)
				=EVAL("loPage." + lcMethod + "()")
			ENDIF
			THIS.RunAll(lcMethod, loPage)
		ENDFOR
		
	CASE LOWER(loContainer.BaseClass) = "grid"
		* For grids, iterate through the columns collection
		FOR EACH loColumn IN loContainer.Columns
			IF PEMSTATUS(loColumn, lcMethod, 5)
				=EVAL("loColumn." + lcMethod + "()")
			ENDIF
			THIS.RunAll(lcMethod, loColumn)
		ENDFOR
ENDCASE

SET EXACT &lcSetExact
Erik Moore
Clientelligence
Previous
Next
Reply
Map
View

Click here to load this message in the networking platform