Saturday, April 29, 2006

Linking Wizard Controls

.NET 2.0 has a wizard control, in which you define steps in markup and then step through them. Starting in December I was working at a client who needed a seven or eight step wizard, with each step having complex validating and navigation requirements. The user control in which we built this wizard became enormous and disorganized, as successive steps used different data structures and sprouted subroutines and event handlers. We wished we could make several sub-wizards of a few related pages each and link them together.

Well, you can, sort of. What you can do is implement a user control that contains a wizard control, implement whatever page-specific logic you can factor out of the big wizard, and then expose the WizardSteps collection as a property. Then you can have your parent user control (with the big wizard) load the user control, but add each step in the WizardSteps property to the WizardSteps collection of the big wizard. The steps will behave to the user as if they were defined in the big wizard, with their titles appearing as steps in the big wizard's sidebar, but the event handlers for all the controls will still be handled by the original user control.

To reference the big wizard, which is now the parent of the steps, set up a private property on the subwizard user control that references the Wizard property of one of the steps. This will now be the big wizard. The subwizard will now be inert and won't have a useful ActiveStepIndex or generate NextStepClicked events. If you need handlers for that in the subwizard user control you'll have to explicitly hook them up to your new Wizard property.

Thursday, April 20, 2006

Client-side objects for server controls

I had a conversation with Chris Peterson on Tuesday regarding the difficulty of manipulating the HTML controls inside composite or templated .NET controls with Javascript. The controls have ids that you can't easily predict unless you are generating the javascript from within the templated control, and even if you could predict them you'd be violating one of the rules of encapsulation, namely that code manipulating an object (your server control) shouldn't have to know the internals of that control.

Given that Javascript can create objects with arbitrary properties, it occurred to me that it would be possible to expose the objects in a .NET templated control as properties of a client-side object, making them available for manipulating by javascript not generated by the control. Validation controls in .NET 2.0 already do this, using the AddExpandoProperty method of the ClientScriptManager object. I see an area here for experimentation.