Code Behind The Form

Refers to the practice in some VisualTools of having snippets of EventHandler code bound to the generated forms, especially where the only way to access the code is from the form-building tools. Tends to atomize the event code, making it extremely difficult to design a coherent event handling system.

Are you saying you want more control over the event-handling mechanism than what most products give, or complaining about event-driven GUI tools in general? Can you give a specific example?

I'm not the original writer, but I have an example from a old tool. I was building a data-entry form that had 10 fields, visually split into 2 columns of 5. The GUI Builder produced 10 widgets, and 10 validation function hooks, when I needed 10 widgets with the same validation hook. --PeteHardie

Just make a function and call that function in 10 places.

[Asynchronous code can be difficult to understand under the best of circumstances, and this is often aggravated in event handling systems where it is difficult to discern who calls what when.]

The particular problem I had in mind is that, because the code module is tied to a specific form (or, in the case of older versions of MicrosoftAccess, were part of the form, and could not be easily separated from it), it is difficult to see where repeated code lies, making abstraction difficult. As a result, you end up with either duplicate code in several places, or else with EventHandlers which are nothing more than calls to the actual code. This is especially problematic when refactoring older code, where the event handlers are already written for each case, and the duplicate code has to be manually hoisted out of the form event code.

For example, in one project I was in using Access (and where the Lead Programmer was the same coder I mentioned in BadProgrammer), I was working on converting five similar Office Management packages (basically accounting systems for different types of small firms - law firms, medical and practices, property management firms, etc., all originally forked off the original Realtor version) from Access 2.0 to Access 97, while adding considerably to the functionality. The code base was a nightmare of duplications, partly because Access 97 did not have a practical way to separate code into libraries (and the MGT didn't want to bother anyway), but partly because the main sequence of DrillDownForms? had on average three similar cascading controls (where a change in one would effect the others, and possibly call up the next form in the sequence), on each of the five or six forms. The chief programmer, as I explained elsewhere, was the sort of fast coder who would rather repeat the same code several times than write one function to handle all cases at once. As a result, many of the changes in the cascading controls would have to be copied twenty times or more. - JayOsako


Being an Access programmer for longer than I prefer to admit, I have had to battle that issue over and over again. I've finally found some ways of dealing with it somewhat. I describe the ways here for anyone who still needs to deal with this issue.

For some kinds of EventHandler, we don't need any event arguments. In these cases, we can simply call a public function or a public function member of the form using the =<function>() syntax. I don't like the fact that these dependencies are now hidden in the UI design and not visible in the code, but we can apply some OffensiveProgramming to help with this. Add code to the Open event handler of the form that checks to see that, of the controls in a list, all those controls and only those controls have that event handler specified, and raise an error explaining the problem if not. At that point, the programmer can update either the list, or the event handlers, whichever is out of date.

For other kinds of EventHandler, where we do need to interact with the event handler parameters, there's a rather heavyweight solution that is sometimes (though not always) better than just duplicating the event handlers. It turns out that you can set up a WithEvents member of a stand-alone class that refers to an individual control and responds to events from the control. What we can do with this is create an event receiver class for each control type, and an event forwarder class used to funnel events from multiple controls back to a single event handler on the form. Each event receiver is given a reference to the control it will receive events from, and a reference to the forwarder that will raise the events again to a single event handler on the form. When setting up the event receivers, we must also set the appropriate event property(ies) of the controls to "[Event Procedure]".

I've used this approach successfully on a calendar form to respond to events from the entire array of Day controls in a consistent way.

-- SteveJorgensen


See VisualBasic, VisualBasicForApplications, MicrosoftAccess, EventDrivenProgramming


CategoryCodingIssues


EditText of this page (last edited December 30, 2007) or FindPage with title or text search