Asp wizard byla jedna z nadějných komponent jistě pro mnoho vývojářů, ale jen do okamžiku než zjistili, jak vypadá vyrendrované HTML, nebo že je téměř nemožné umístit „Sidebar“ nahoru. MS tyto komponenty dělá tak, aby pokud možno fungovaly po přetažení do okna návrháře a vyžadovaly co nejméně doplňujícího kódu. Ale to je do jiného příspěvku...

Ostatně jako u jiných komponent. Naštěstí pro nás existuje již dlouho i možnost použít CSS Friendly Control adapters. Ty základní jsou ke stažení na serveru asp.net, další si již každý musí dopsat sám nebo najít na webu.

Protože jsem chtěl použít právě wizard, ale podmínkou bylo ono umístění Sidebaru nahoru, před tím než jsem se pustil do psaní vlastního adaptéru, porozhlídl jsem se po webu a našel již hotové řešení. Postaral se o něj Andrew Tokeley a naleznete ho zde.

Po otestování jsem si Sidebar ještě doplnil o ul a li elementy, abych mohl použít již hotové css.

...

writer.RenderBeginTag(HtmlTextWriterTag.Ul);
                                        
                    foreach (WizardStep step in wizard.WizardSteps)
                    {
                        // Find the control within the container that contains the linkbutton
                        Control control = listContainer.Controls[listIndex];

                        // Find the LinkButton itself
                        LinkButton linkButton = control.FindControl(CONTROLID_SIDEBARBUTTON) as LinkButton;

                        // Get the postback javascript code and register the LinkButton control so that we can 
                        // raise postback events 
                        string javascript = Page.ClientScript.GetPostBackClientHyperlink(linkButton, "", true);

                        // Render the LinkButton using Anchors
                        writer.RenderBeginTag(HtmlTextWriterTag.Li);
                        writer.WriteBeginTag("a");
                        if (wizard.ActiveStepIndex == listIndex)
                        {
                            writer.WriteAttribute("class", CSS_ACTIVE);
                        }
                        writer.WriteAttribute("href", javascript);
                        writer.WriteAttribute("id", linkButton.ClientID);
                        writer.Write(HtmlTextWriter.TagRightChar);
                        writer.Write(step.Title);
                        writer.WriteEndTag("a");
                        writer.RenderEndTag();

                        writer.WriteLine();

                        listIndex++;
                    }

                    writer.RenderEndTag();
                }

a vykreslování ovládacích tlačítek jsem upravil, tak aby se nejříve provedl test zda přidat Finish button:

// If on first page of wizard
                    if (wizard.ActiveStepIndex == 0)
                    {
                        RenderStartNavigation(writer, wizard);
                    }
                    else if (wizard.ActiveStepIndex == wizard.WizardSteps.Count - 2)
                    {
                        RenderFinishNavigation(writer, wizard);
                    }
                    else if (wizard.ActiveStepIndex < (wizard.WizardSteps.Count - 1))
                    {
                        RenderStepNavigation(writer, wizard);
                    }                 
                    else
                    {
                        // Yikes
                    }

No a je to. Pokud přijdete na nějaký problém, dejte prosím vědět. Pokud víte o dalších volných adaptérech sem s nimi. Určitě udělají radost i dalším.