Groups | Blog | Home
all groups > asp.net building controls > february 2007 >

asp.net building controls : Designer Support for Derived Wizard Class


Mark Olbert
2/16/2007 7:38:15 AM
I've written a "SmartWizard" class that essentially adds initialization and exit handlers for the individual steps, allowing for
easier control over how a user walks through the wizard.

But I've run into a problem with the design-time support. With a regular Wizard, clicking on a step in the sidebar brings up that
step in the designer. In my derived class that doesn't happen. In fact, nothing happens. The code for the derived SmartWizard class
is pretty simple (all the logic is in a support class), so I don't think that's the problem. Adding a Designer(WizardDesigner)
attribute to the SmartWizard class doesn't do anything, either.

How does the Wizard control work its magic at design-time? Is it shadowing the sidebar links in the custom designer class and then
reacting to events there?

Mark Olbert
2/16/2007 7:56:59 AM
Walter,

My apologies, I forgot that you'd replied to my earlier post on this subject. I'm continuing the discussion here.

I did the test that you suggested, and was able to confirm that the simple derived Wizard class does exhibit the correct design-time
behavior. Which is really confusing, since the code for my custom wizard class is pretty simple:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.Design.WebControls;

namespace OlbertMcHughLLC.Web
{
[ToolboxData("<{0}:SmartWizard runat=server></{0}:SmartWizard>")]
[Designer(typeof(WizardDesigner))]
public class SmartWizard : Wizard
{
private SmartWizardInfo info;

protected override void OnInit( EventArgs e )
{
base.OnInit(e);

info = new SmartWizardInfo(this);
}

protected override object SaveControlState()
{
object baseState = base.SaveControlState();

return new Pair(baseState, info.ControlState);
}

protected override void LoadControlState( object state )
{
Pair thePair = state as Pair;

if( thePair != null )
{
base.LoadControlState(thePair.First);

info.ControlState = (ControlStateInfo) thePair.Second;
}
}

protected override void OnFinishButtonClick( WizardNavigationEventArgs e )
{
if( info.OnActiveStepChanged(WizardSteps.Count - 1, WizardSteps.Count) )
{
info.SuppressNextActiveStepChanged = true;

base.OnFinishButtonClick(e);
}
else e.Cancel = true;
}

protected override void OnPreviousButtonClick( WizardNavigationEventArgs e )
{
if( info.OnActiveStepChanged(e.CurrentStepIndex, e.NextStepIndex) )
{
info.SuppressNextActiveStepChanged = true;

base.OnPreviousButtonClick(e);
}
else e.Cancel = true;
}

protected override void OnNextButtonClick( WizardNavigationEventArgs e )
{
if( info.OnActiveStepChanged(e.CurrentStepIndex, e.NextStepIndex) )
{
info.SuppressNextActiveStepChanged = true;

base.OnNextButtonClick(e);
}
else e.Cancel = true;
}

protected override void OnSideBarButtonClick( WizardNavigationEventArgs e )
{
if( info.OnActiveStepChanged(e.CurrentStepIndex, e.NextStepIndex) )
{
info.SuppressNextActiveStepChanged = true;

base.OnSideBarButtonClick(e);
}
else e.Cancel = true;
}
}
}

Granted, there's a lot of stuff in the SmartWizardInfo object, but not in the derived Wizard class itself.

I thought that maybe some of the code in the SmartWizardInfo class might be responding to events at design-time, but when I set the
debugger to stop inside the OnSideBarButtonClick() handler, the breakpoint was never hit (I was running a second instance of VS2005
as the "host" application from within the instance of VS2005 where I was working on the SmartWizard code at the time).

Any thoughts as to how to proceed?

- Mark


[quoted text, click to view]
Mark Olbert
2/16/2007 8:09:29 AM
Walter,

Problem solved. I forgot that I'd hooked the ActiveStepChanged event inside SmartWizardInfo, and some of the custom step handling
logic was blocking the switch to a new step. Interestingly, the designer doesn't invoke OnSideBarButtonClick() -- it must just set
the ActiveStepIndex directly -- which is why the initial breakpoint I'd set never got hit.

Thanks for your help!

AddThis Social Bookmark Button