The default style of the ASP.NET Wizard control is not the best. For the sidebar to work, and display all the wizard steps in a wizard requires quite a bit of space. And in all the wizards we end up creating, we don't want the user to jump from one step to the next using the sidebar. We make the user click from step to step linearly.

We've spent a little time lately changing the way the wizard looks and have come up with the following look and feel.

wizardDetails

The top HeaderTemplate contains the current step the user is on (derived from the WizardStep Title) and an indication of the total number of step (we use three different classes in indicate the current step, completed step and incomplete step). The "steps" also have tooltips added to let the user know what steps are coming. (See image below)

 Tooltip when Mouse hovers over the step number

The WizardStep in the image above is all the information regarding "Billing and Shipping" details (this is just standard Wizard Step stuff)

How its done

The markup for the wizard aspx code is as follows:

<asp:Wizard ID="wzd" runat="Server" Width="100%" DisplaySideBar="false">
    <HeaderTemplate>
        <table style="width: 100%" cellpadding="0" cellspacing="0">
            <tr>
                <td class="wizardTitle">
                    <%= wzd.ActiveStep.Title%>
                </td>
                <td>
                    <table style="width: 100%; border-collapse: collapse;">
                        <tr>
                            <td style="text-align: right">
                                <span class="wizardProgress">Steps:</span>
                            </td>
                            <asp:Repeater ID="SideBarList" runat="server">
                                <ItemTemplate>
                                    <td class="stepBreak">&nbsp;</td>
                                    <td class="<%# GetClassForWizardStep(Container.DataItem) %>" title="<%# DataBinder.Eval(Container, "DataItem.Name")%>">
                                        <%# wzd.WizardSteps.IndexOf(Container.DataItem as WizardStep) + 1 %>
                                    </td>
                                </ItemTemplate>
                            </asp:Repeater>
                        </tr>
                    </table>
                </td>
            </tr>
        </table>
    </HeaderTemplate>
    <SideBarTemplate>
    </SideBarTemplate>
    <WizardSteps> ... removed... </WizardSteps>
</asp:Wizard>

We add the following event handler to Page_Load in our code-behind

protected void Page_Load(object sender, EventArgs e)
{
    wzd.PreRender += new EventHandler(wzd_PreRender);
}

And have the following methods in the code-behind

protected void wzd_PreRender(object sender, EventArgs e)
{
    Repeater SideBarList = wzd.FindControl("HeaderContainer").FindControl("SideBarList") as Repeater;

    SideBarList.DataSource = wzd.WizardSteps;
    SideBarList.DataBind();

}

public string GetClassForWizardStep(object wizardStep)
{
    WizardStep step = wizardStep as WizardStep;

    if (step == null)
    {
        return "";
    }

    int stepIndex = wzd.WizardSteps.IndexOf(step);

    if (stepIndex < wzd.ActiveStepIndex)
    {
        return "stepCompleted";
    }
    else if (stepIndex > wzd.ActiveStepIndex)
    {
        return "stepNotCompleted";
    }
    else
    {
        return "stepCurrent";
    }
}

Explanation of the code above

When the wizard goes into PreRender, we bind the collection of WizardSteps to the Repeater in our HeaderTemplate

The "GetClassForWizardStep" is a helper method we have to determine what wizard step we're on, and render the appropriate class in the table cell.

Style Sheet Rules

The rules I'm using above to generate the page are as below...

/* WIZARD */
.stepNotCompleted
{
    background-color: rgb(153,153,153);
    width: 15px;
    border: 1px solid rgb(153,153,153);
    margin-right: 5px;
    color: White;
    font-family: Arial;
    font-size: 12px;
    text-align: center;
}

.stepCompleted
{
    background-color: #4d4d4d;
    width: 15px;
    border: 1px solid #4d4d4d;
    color: White;
    font-family: Arial;
    font-size: 12px;
    text-align: center;
}

.stepCurrent
{
    background-color: #e01122;
    width: 15px;
    border: 1px solid #e01122;
    color: White;
    font-family: Arial;
    font-size: 12px;
    font-weight: bold;
    text-align: center;
}

.stepBreak
{
    width: 3px;
    background-color: Transparent;
}

.wizardProgress
{
    padding-right: 10px;
    font-family: Arial;
    color: #333333;
    font-size: 12px;

}

.wizardTitle
{
    font-family: Arial;
    font-size: 120%;
    font-weight: bold;
    color: #333333;
    vertical-align: middle;