ASP.NET 2.0 Wizard Control

One of the useful new controls in ASP.NET 2.0 is the <asp:wizard> control, which allows developers to easily create multi-step UI (with built-in previous/next functionality and state management of values).

There is a nice 14 minute online video now available that walks through how to build an ASP.NET 2.0 application from scratch that provides a customer online signup form system using the <asp:wizard> control, the asp.net validation controls, and the new System.Net.Mail mail library.  You can watch it being built from scratch and learn the high-level concepts of how the Wizard control works here (to find other short task-focused videos in the new ASP.NET 2.0 "How Do I" series click here).

Here are a few other articles you can read to learn more about the <asp:wizard> control and how to take advantage of it:

One nice tip/trick you can use with the Wizard control is to host it within the new <atlas:updatepanel> control -- which turns the wizard into an Ajax based wizard (no full page post-backs required).  This is trivial to-do and doesn't require any code changes.  This past blog post of mine talks a little about using the <atlas:updatepanel> with the december CTP drop of Atlas, and builds an Ajax task-list in 39 lines of code with it (no javascript required -- it can all be done with C#).  You can learn more about the January CTP drop (which has a lot of enhancements and new features for the <atlas:updatepanel> here).

Hope this helps,

Scott

 

36 Comments

  • Scott -



    Long ago in a conference room far far away, I was talking to you and Thomas Lewis about how much I needed a wizard control. I had been using what the DNN team had, pretty much undocumented, in V3 of DotNetNuke - but it wasn't meeting my needs - and most of the time DNN was overkill for what I needed.



    Well back around the RC days of VS2005 I dug into the the Wizard control you guys were providing. In a matter of a few hours I was completely sold. It was so easy to implement, it handled state management so simply, it was -well - just great.



    As a fan of providing users with task-based workflows, it has been a really welcomed addition to my toolbox.



    Now, when are we going to see the demo of the Wizard control interacting with some Windows Workflow stuff... That will be sweet.



    But in the meantime, thanks to the team for ASP.NET 2.0 &amp; VS 2005 - they really have opened up a world of possibilities.



  • Is there a way to render the wizard control with &lt;div&gt; tags and the navigation links above the control rather than a sidebar (ideally as &lt;ul&gt;&lt;li&gt; as tabs, like many step-by-step applications)?

  • Scott,



    Can you post a demo for the following scenario or at least tell me if it's possible to accomplish?



    I'm new to atlas (as most are) and I'm willing to jump in and learn, but I'd like to first like know how deep the pool is.



    Wrap an asp:wizard in the atlas:updatepanel, but let's say on the first step the user selects an option from a select box, ajax dynamically then creates step 2 based on the user's selection.



    Thank you for the consideration and for posting on this subject.



    Rick



  • Hi Andrew,



    You can use a feature we call &quot;Control Adapters&quot; to override the rendering of controls (for example: to use CSS instead of tables for layout).



    We have some samples + built-in CSS adapters coming out in about a month that you'll be able to use to do this easily for many controls.



    Hope this helps,



    Scott

  • Hi Rick,



    I will add that scenario to my list of blog posts to make (note: the list is a little long at the moment -- so it might take a bit). I think you'll find it pretty easy though.



    Hope this helps,



    Scott

  • Shame then that the Wizard does not fully support databinding of controls within it.



    You can read values from a datasource but not write them back into a datasource control so it is useless for collecting information unless you manually code the links (as I had to).

  • Hi Howard,



    You should be able to use data-binding within the templates. What scenario are you specifically trying to-do?



    Thanks,



    Scott

  • Hi Matt,



    I just forwarded a link to your question off to someone on the team to hopefully help with.



    Thanks,



    Scott

  • Following on from Howard's comments above, I think his point is that the datasource binding does not span all the steps in the wizard. &nbsp;This seems at odds with "transactional" nature of the wizard. Ideally I want to databind all controls in all steps of the wizard when IsPostBack==false, and update the database when the wizard is finished.

  • Thinking about this some more, I going to try a FormView and use a Wizard control within the EditTemplate.



    Would there be any issues with that?



    Thanks

    Martin

  • Hi Martin,

    I believe that should work just fine.

    Good luck with it!

    Scott

  • I've tried the approach Martin suggests (Wizard inside FormView) against an ObjectDataSource with no luck. On update, all fields are null. If I convert my Wizard to a MultiView control (and roll all the Wizard-y logic myself), everything works fine... I saw a couple of bugs fly by during beta about this being broken for MultiView- I'm wondering if there's still something lurking that prevents this from working with a Wizard? Found a few references to similar issues whilst googling, but not a lot of info out there...

  • I have experienced major problems with using third party controls as child controls of the Wizard. Do you know of a good article on why there are so many problems? Even Infragistics' WebHTMLEditor control refuses to work with it.

  • Hi David,

    My guess is that some control might have issues with the next/previous semantics (since the Wizard is using a new template feature in ASP.NET that older code might not support being nested within).

    Have you tried contacting Infragistics to see if they know of the issue?

    Thanks,

    Scott

  • Hi Matt,

    If you want to send me email (scottgu@microsoft.com) with a .zip file of a simple sample showing th error, I can ask someone on the team to take a look at it.

    Thanks,

    Scott

  • Hi, Scott I have played with the Wizard today and it's cool. What I want is the "Next" button disabled until I do something in the step. However, I couldn't find a way to do that. Can you please help me? Thanks in advance Tom

  • Hi Tom,

    You could probably disable the next button using some client-side javascript, and then re-activate it when the action has occured during that step. Unfortunately I don't have a good sample that shows how to-do this - but theoretically it should be possible.

    Hope this helps,

    Scott

  • Hi Matt/Scott,



    Have you got any further on this? &nbsp;I'm about to start implementation. &nbsp;Any good info to link to?



    Thanks

    Martin

  • Looking at nesting wizard within formview further, there seem to be two issues (so far)...



    1) Databound &nbsp;controls in wizard steps are not easily surfaced in the containing web page (because the wizard control is nested in the formview control)

    2) The form view control doesn't realise that these databound controls should play a part in FormView CRUD operations.



    The way I expect to work round this is:

    1) Have a page based event handler for Wizard navigation button clicks. &nbsp;From this handler I can access the wizard's databound controls with an expression like:

    ((TextBox)((Wizard)sender).WizardSteps[0].Controls[5]).Text

    I can then set some temporary variable to store this value.

    I then will call FormView1.InsertItem(false) from the navigation button handler.

    2) Have a handler for the ItemInserting event.

    Manipulate the FormViewInsertEventArgs Values collection, using the temporary variable stored earlier.



    It's quite painful, but should work.

    One downside is if the databound fields move from one step to another, I have to change the expression above.



    However, is there a better way???

    1) How can I get the wizard's databound to controls surface at the page level for easy access, like they are when not nested?

    2) How can I get the FormView control to automatically use the databound controls in the CRUD operations data collection?



    Are there any parameter/method attributes that I should be using?



    Thanks in advance.

    Martin



  • I have had trouble using client-side javascript because the wizard renames my dropdownlists and textboxes. &nbsp;Using the document.form.control name or getElementByID both fail if .NET renames the controls at runtime. &nbsp;I have had to too many problems with the wizard - not ready for prime time in my view. &nbsp;Going back to the old way of doing things.

  • Nancy,



    You can create the javascript function dynamically in your server side code, and then register it using ClientScriptManager.RegisterClientScriptBlock



    When you create the string for the function, use myDllControl.UniqueID to get round your problem.



    HTH

    Martin

  • Martin,

    Can you please provide a code sample on how to do this? (i.e. using myDllControl.UniqueID). I have the same problem as Nancy, and need help.

    Thanks,

    Irena

  • Better yet why not use ASP.NET input validation controls... when user clicks on Next button and the wizard page (one of the controls on the wizard page) is NOT in valid state, the ASP.NET Validation pluming will not allow the Wizard to advance. elegant solution Mike WinInsider.com

  • I've just gone through the 14 minute online video.
    Everything's great except the RangeValidator.
    It's a bit strange that the rating field accepts value that is greater than 5 when I ran the demo. If I change the type of the RangeValidator to Integer, then it would work as expected. But I didn't see the type's been changed to Integer in the demo. Did I miss out something?

  • Has there been any further news/progress in getting the wizard control to work properly with databinding in the formview?

  • Have exactly the same problem with using client-side javascript because the wizard renames my controls. Does anybody have a solution?

  • Hi Andrew,

    Can you email me a .zip file that illustrates the problem you are having? I can then have someone look at it.

    Thanks,

    Scott

  • If you try to customize the wizard by putting textbox control for example,and tryto get its value on another step,it doesn't update it value if you changed it than the loaded data ????why this happen ?

  • Hi,

    I'm trying to do some databinding on each step. IE: They are entering in an email address and I'm trying to see if it is in the database before I proceed to the next step. I'm using the SQL control as we hae a 2005 sql db here but I cannot seem to get it working. I don't suppose anyone could provide some examples of how to go about doing this?


  • I try to hide step next button programtically thorugh runtime.

    i tried to get the control by findControl or by using control collection in wizard,all of them return null.


    1)
    Button btnNext = (Button)Wizard1.FindControl("StepNextButton");
    btnNext.Visible = false;

    2)
    Button btnNext = (Button)Wizard1.Controls[0].FindControl("StepNextButton");
    btnNext.Visible = false;

    both of these solution doesn't work.

  • Hi Scott,

    I have been reading your blog for a while and have found it very useful, so thanks.

    Can you help me with a problem regarding the wizard control?

    I have a wizard set up with 5 steps. Step 3 of 5 takes a number of members. Step 4 then dynamically calls an ascx user control onto the step 4 wizard n times (where n is the amount of members).

    So my problem is, when I am on step 5, then hit previous none of the controls or data is rendered, the page is just blank. I guess this is becuase the controls are being rendered dynamically after the pageinit() event that the Wizard resides on.

    Is there a way to resolve this issue, or another work around that will allow me to create dynamic content on step 4 while the content, and data entered into that content is remembered when I use the previous button from step 5?

  • Hi Martyn,

    Can you send me email that describes this scenario more and ideally a small .zip file with a repro? I will then loop in someone on the team who knows the Wizard control better and might be able to help.

    Thanks,

    Scott

  • Hello Scott,

    Before I get started, I must say I went to your lectures at tech-ed 2006 in Auckland NZ, and really enjoyed every moment of them. What a terrific conference.

    I am currently developing a web application that, well, is basically a large .NET wizard control. It is being created in VS2005 (of course) and uses the provider model architecture.

    Basically, on each WizardStep of the wizard control data is submitted to an SQL database when the user hits the NextButton. This is done using a stored procedure via a sqlProvider.

    But what I would like is after the Nextbutton click event occurs and the data is sent to the DB, a new step is dynamically created which contains the same controls as the previous step. Therefore, the same process can occur until the user selects the selects FinishButton.

    I am thinking that this might not be possible due to the wizard control having defined control ID's present through all steps. I have scowered the internet but can't seem to locate very much in-depth info regarding advanced wizard control scenarios.

    Is it possible to create WizardSteps in a wizard control dynamically during runtime? And if so, is it possible to re-use WizardStep controls?

    Regards,
    Scott (also)

  • Hi Scott,

    You probably could dynamically load a Wizard's step with controls - although to be honest with you, you might find it easier to just build the wizard UI yourself for this case using an control for the dynamic content, and your own next/previous navigation button.

    The benefit of building your own is that you'll have an easier time pulling the previous content from the database, and will have complete control over the UI.

    Hope this helps,

    Scott

  • Hi Jagan,

    Can you put together a simple example of this issue and send it to me via email (as a .zip file)? I can then take a look for you.

    Thanks,

    Scott

  • Moustafa,

    I was looking to show/hide the wizard buttons too. I came up with a hack that does the trick, set the wizardbutton's buttontype to ButtonType.Link, and then set the wizardbutton's buttontext to string.Emtpy.

    you can wrap it in a little toggle function and call it whenver is appropriate:

    private void WizardButtonDisplay(bool Show)
    {
    if (Show)
    {
    Wizard.StepPreviousButtonType = ButtonType.Button;
    Wizard.StepPreviousButtonText = "Previous";
    Wizard.FinishCompleteButtonType = ButtonType.Button;
    Wizard.FinishCompleteButtonText = "Next";
    Wizard.StartNextButtonType = ButtonType.Button;
    Wizard.StepNextButtonText = "Finish";
    }
    else
    {
    Wizard.StepPreviousButtonType = ButtonType.Link;
    Wizard.StepPreviousButtonText = string.Empty;
    Wizard.FinishCompleteButtonType = ButtonType.Link;
    Wizard.FinishCompleteButtonText = string.Empty;
    Wizard.StartNextButtonType = ButtonType.Link;
    Wizard.StepNextButtonText = string.Empty;
    }
    }

Comments have been disabled for this content.