[AccessD] Building a control class

John W Colby jwcolby at gmail.com
Mon Mar 16 09:35:13 CDT 2009


AD,

The frmClass is in fact a wrapper to the form object, so of course in 
that case declaring the form objects WithEvents and sinking any and all 
events is expected.

As for sinking form events in control objects in the "one to many" 
relationship, I understand what you are saying.  It does indeed make 
programming easier in the sense that the control class obtains control 
of the form's event directly and the form does not have to iterate a 
collection and call a method of a slew of different control classes.  
However it also gives you much less control in dictating when control is 
passed to the control class.  For example suppose that in your form 
class you had a situation like this:

sub mFrm_Current()

    do something
    do something else that has to be done before the control classes get 
control
    >>>call the controls to do something
    do something that needs the controls initialized
    do something else
end sub

As you can see, if the control classes get control automatically they 
will get control AFTER mfrm_Current finishes processing and exits the 
sub.  The order of code execution is a simple "which object was 
instantiated first".  The form object was instantiated first, and in 
fact the scanner in the control class instantiates all of the control 
classes, so all of its processing will totally complete before the 
control classes are allowed to gain control.

Now you as a programmer may not care, but just keep that in mind.

The important point in this discussion is not that "it has to be done 
this way" but rather that you understand the concepts involved, that you 
understand the details involved, and that you as a programmer can make 
an educated decision how to do this based on your own desires and needs.

I attempt to teach "best practices", and one of the precepts of classes 
and best practices for classes is that you design an interface and then 
program to that interface.  The methods and properties of the control 
class are its interface.  Raising events are an interface.  By using 
these two interfaces you "decouple" the control classes from the form 
class. 

As an example I can and do very occasionally use the control classes 
DIRECTLY in the form's code behind form.  If the control's class is 
expecting to be passed either the form class or the form itself, and to 
perform processing specific to a particular problem, then using the 
class directly in the form's code behind form becomes problematic.  The 
control class is no longer decoupled from the form or clsFrm, it 
explicitly depends on that object.

I do in fact pass in a pointer to parent, but there are many places 
where I just set that to null when calling the mInit.  Thus if no valid 
parent exists, no problem.

Again, I am not discouraging you from actually declaring the form 
WithEvents in the control class, I am simply pointing out that every 
shortcut caries with it a potential problem.  OOP has evolved over the 
last decades and lots of people contributed tons of ideas, and some of 
these distilled down into the "interface" concepts.  I think it is 
perfectly OK to buck "the thinking" as long as you know why the thinking 
exists, have specific reasons to go against the thinking, and know what 
the ramifications are.

You are one of the people I would be most comfortable watching go your 
own way simply because you obviously have a very firm grasp of how and 
why things work, and can get yourself out of any problems you might 
encounter.

John W. Colby
www.ColbyConsulting.com



A.D.Tejpal wrote:
> John,
>
>     Thanks for your generous observations and kind words. I had been procrastinating active study of classes, setting it aside for some future date. Some time back, in another thread, Gustav had pointed out the benefit of using WithEvents. Your lecture series has been instrumental in my getting further into it. It is an exhilarating experience and I can't thank you enough.
>
>     The problem of projecting form class events into control class has since been resolved. It was found to be a matter of timing the instantiation, which should have been done in the property procedure (in control class) meant for setting the parent class property. Incidentally, for raised events, even though pertaining to form object, hooking via "[Event Procedure]" is not involved.
>
>     It is seen that one level of circular reference does in any case come into play in each control class while setting up the parent property. Using WithEvents qualifier for the object variable (in control class) meant for holding a pointer to parent class, should not impose any extra strain on inter-class reference status.
>
>     If instead, an object variable (WithEvents) is used for setting a pointer either to the form object variable in form class or directly to the real form (via parent property of control object argument passed to control class in its Init subroutine), it results in a second level of circular reference, over and above that existing between control class and form class as stated in preceding para. Though it works, such a state of multiple intersecting circular references, is found detrimental to proper termination and deserves to be considered forbidden.
>
>     In certain situations, trapping form class events in control class can have its advantages. For example, various types of controls might be required to have different response to form's current event. If it were to be handled purely within form' current event in form class, it would require a set of statements, each with a loop, to activate the methods of individual control class objects in the collection. Local action in control class, by trapping form class events appears to offer simpler alternative. As a general principle, in one to many class object relationship, local implementation on the many side, if feasible, looks preferable.
>
>     Effectiveness of the approach outlined in previous para, has been tested for the following features:
>     (a) Form navigation combo box with two way synchronization.  
>     (b) Dynamic filtration of look-up list for combo box.
>
>     Note:  It is observed that for (b) above, a combination of form's current event (applying unfiltered row source) and combo's enter event (applying filtered row source) is adequate. No other event appears to be needed (e.g. form's Load event and combo's Exit / GotFocus / LostFocus events).
>
> Best wishes,
> A.D. Tejpal
> ------------
>   



More information about the AccessD mailing list