Adding, Changing & Finding buttons in the ASP.NET Wizard Control
A comment was recently left on a previous post of mine asking how to go about adding a button to a wizard and handling the click. I thought I'd answer the question with another post as there is usually more you'd like to do than just adding a button (we certainly do!!!!)
Adding a button to the Wizard and handling the onclick event
Adding a button to the ASP.NET wizard is pretty simple and pretty easy to manage. You just have to define the StartNavigationTemplate, StepNavigationTemplate and FinishNavigationTemplate. These are what define the rendering of the buttons at the bottom of the wizard.
<asp:Wizard ID="wzd" runat="Server" Width="100%" DisplaySideBar="false"> <WizardSteps> <asp:WizardStep ID="step1" runat="server" StepType="Start"> ... omitted ... </asp:WizardStep> <asp:WizardStep ID="step2" runat="server" StepType="Step"> ... omitted ... </asp:WizardStep> <asp:WizardStep ID="step3" runat="server" StepType="Finish"> ... omitted ... </asp:WizardStep> </WizardSteps> <StartNavigationTemplate> <table cellpadding="3" cellspacing="3"> <tr> <td> <asp:Button ID="btnCancel" runat="server" Text="Cancel" CausesValidation="false" OnClientClick="return confirm('Are you sure you want to cancel');" OnClick="btnCancel_Click" /> </td> <td> <asp:Button ID="btnNext" runat="server" Text="Next >>" CausesValidation="true" CommandName="MoveNext" /> </td> </tr> </table> </StartNavigationTemplate> <StepNavigationTemplate> <table cellpadding="3" cellspacing="3"> <tr> <td> <asp:Button ID="btnCancel" runat="server" Text="Cancel" CausesValidation="false" OnClientClick="return confirm('Are you sure you want to cancel');" OnClick="btnCancel_Click" /> </td> <td> <asp:Button ID="btnPrevious" runat="server" Text="<< Previous" CausesValidation="false" CommandName="MovePrevious" /> <asp:Button ID="btnNext" runat="server" Text="Next >>" CausesValidation="true" CommandName="MoveNext" /> </td> </tr> </table> </StepNavigationTemplate> <FinishNavigationTemplate> <table cellpadding="3" cellspacing="3"> <tr> <td> <asp:Button ID="btnCancel" runat="server" Text="Cancel" CausesValidation="false" OnClientClick="return confirm('Are you sure you want to cancel');" OnClick="btnCancel_Click" /> </td> <td> <asp:Button ID="btnFinish" runat="server" Text="Finish" CausesValidation="true" CommandName="MoveComplete" /> </td> </tr> </table> </FinishNavigationTemplate> </asp:Wizard>In the ASP.NET code above, I've added 3 steps to my wizard, each with a different StepType. The StepType is what defines which NavigationTemplate the ASP.NET wizard uses.
In the example above:
- Step 1 will use the "StartNavigationTemplate"
- Step 2 will use the "StepNavigationTemplate"
- Step 3 will use the "FinishNavigationTemplate"
The trick with making your own NavigationTemplates is to make sure you use the "CommandNames" that the ASP.NET wizard requires. You can see on the "Next", "Previous" and "Complete" buttons that there are no "OnClick" handlers, rather we have used "MoveNext", "MovePrevious" and "MoveComplete" as the CommandNames on the buttons. These CommandNames are what the wizard uses to fire the appropriate event.
In all the cases above, I've added a button that allows the user to "Cancel". When the user clicks on "Cancel", it fires a quick javascript confirm. If the user presses "OK", then the normal code-behind button event handler is raised.
protected void btnCancel_Click(object sender, EventArgs e) { // Do something with the click ... Response.Redirect("home.aspx"); }
Finding a button in a NavigationTemplate
Sometimes we want (or need) to hide a button on one of the wizard steps for whatever reason.
For example, if you are using a wizard for an e-commerce checkout, you might disable the Next button on the first step if there are no items in your shopping basket.
This code below is from someone else, so I can't take credit for it.... I'm not sure where we got it from, but it works.
public enum WizardNavigationTempContainer { StartNavigationTemplateContainerID = 1, StepNavigationTemplateContainerID = 2, FinishNavigationTemplateContainerID = 3 } private Control GetControlFromWizard(Wizard wizard, WizardNavigationTempContainer wzdTemplate, string controlName) { System.Text.StringBuilder strCtrl = new System.Text.StringBuilder(); strCtrl.Append(wzdTemplate); strCtrl.Append("$"); strCtrl.Append(controlName); return wizard.FindControl(strCtrl.ToString()); }
The ASP.NET wizard does some weird stuff with naming, and you can't use the standard FindControl() to find the control. If you're using .NET 3.5, you could probably implement the above "GetControlFromWizard" as an Extension Method.
Hiding the button
Now that we know how to find the button in the wizard step, we can hide/disable... do anything we want to the button.
protected void Page_Load(object sender, EventArgs e) { if (Page.User.Identity.IsAuthenticated == true) { Button btnNext = GetControlFromWizard(wzd, WizardNavigationTempContainer.StartNavigationTemplateContainerID, "btnNext") as Button; btnNext.Enabled = false; } }
In the code above, I'm checking if a user is Authenticated.. and if they are, then I hide the button. As I said before, you could implement what condition you wanted to do here.
Putting it all together
Using the techniques I've used here, and the techniques described in my previous post, you can actually make some pretty nice looking wizards using the ASP.NET Wizard control. We use the methods I've shown here, and the methods in my previous post together and we've produced some pretty user-friendly wizards.