Na obsah stránky

Beztabulkové renderování controlů v ASP.NET 2.0

Aleš Roubíček | | # permalink

Již delší dobu jsem se pídil po tom, jak vyřešit takový malý problém s asp:Login controlem a podobným, které se dají krásně přepsat pomocí šablonování, ale vždy zůstane obalová tabulka. Tato tabulka je natvrdo napsaná v kódu tohoto velice užitečného controlu. Každá třída odvozená od WebControl má definovaný základní element, od kterého se odvozuje renderování výsledného kódu. Bázovým elementem všech složitějších controlů je v ASP.NET 2.0 právě element table, čímž se porušují pravidla přístupnosti a vůbec semantický pohled na výsledný XHTML.

Nakonec jsem našel řešení na jednom blogu a ještě ho trochu poupravil.

using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

namespace PBSoftware.Gryphoon.Controls
{
        public class Login : System.Web.UI.WebControls.Login
        {
                protected override HtmlTextWriterTag TagKey
                {
                        get
                        {
                                return HtmlTextWriterTag.Div;
                        }
                }

                protected override void Render(HtmlTextWriter writer)
                {
                        WebControl div = new WebControl(TagKey);

                        if (LayoutTemplate == null)
                                LayoutTemplate = new LoginTemplate();

                        LayoutTemplate.InstantiateIn(div);

                        Controls.Clear();
                        Controls.Add(div);

                        div.CopyBaseAttributes(this);
                        div.RenderControl(writer);
                }
        }

        public class LoginTemplate : ITemplate
        {
                public LoginTemplate() { }

                public void InstantiateIn(Control container)
                {
                        HtmlGenericControl fieldset = new HtmlGenericControl("fieldset");
                        HtmlGenericControl legend = new HtmlGenericControl("legend");
                        legend.InnerText = "Přihlášení do aplikace";

                        Label userNameLabel = new Label();
                        userNameLabel.ID = "UserNameLabel";
                        userNameLabel.AssociatedControlID = "UserName";
                        userNameLabel.Text = "Uživatel:";

                        TextBox userNameTextBox = new TextBox();
                        userNameTextBox.ID = "UserName";

                        RequiredFieldValidator userNameRequired = new RequiredFieldValidator();
                        userNameRequired.ID = "UserNameRequired";
                        userNameRequired.ControlToValidate = "UserName";
                        userNameRequired.ErrorMessage = "Uživatelské jméno je povinné.";
                        userNameRequired.ToolTip = "Uživatelské jméno je povinné.";
                        userNameRequired.Text = "*";
                        userNameRequired.ValidationGroup = "Login1";

                        Label passwordLabel = new Label();
                        passwordLabel.ID = "PasswordLabel";
                        passwordLabel.AssociatedControlID = "Password";
                        passwordLabel.Text = "Heslo:";

                        TextBox passwordTextBox = new TextBox();
                        passwordTextBox.ID = "Password";
                        passwordTextBox.TextMode = TextBoxMode.Password;

                        RequiredFieldValidator passwordRequired = new RequiredFieldValidator();
                        passwordRequired.ID = "PasswordRequired";
                        passwordRequired.ControlToValidate = "Password";
                        passwordRequired.ErrorMessage = "Heslo je povinné.";
                        passwordRequired.ToolTip = "Heslo je povinné.";
                        userNameRequired.Text = "*";
                        passwordRequired.ValidationGroup = "Login1";

                        CheckBox rememberMe = new CheckBox();
                        rememberMe.ID = "RememberMe";
                        rememberMe.Text = "Pamatuj si mě.";

                        Literal failureText = new Literal();
                        failureText.ID = "FailureText";
                        failureText.EnableViewState = false;

                        Button loginButton = new Button();
                        loginButton.ID = "LoginButton";
                        loginButton.CommandName = "Click";
                        loginButton.Text = "Přihlásit se";
                        loginButton.ValidationGroup = "Login1";

                        HtmlGenericControl br = new HtmlGenericControl("br");

                        fieldset.Controls.Add(legend);
                        fieldset.Controls.Add(userNameLabel);
                        fieldset.Controls.Add(userNameTextBox);
                        fieldset.Controls.Add(userNameRequired);
                        fieldset.Controls.Add(br);
                        fieldset.Controls.Add(passwordLabel);
                        fieldset.Controls.Add(passwordTextBox);
                        fieldset.Controls.Add(passwordRequired);
                        fieldset.Controls.Add(br);
                        fieldset.Controls.Add(rememberMe);
                        fieldset.Controls.Add(failureText);
                        fieldset.Controls.Add(loginButton);

                        container.Controls.Add(fieldset);
                }
        }
}

Předem upozorňuju, že tento control musí mít přidělenou nějakou šablonu, jinak nebude fungovat. Ještě na tom zapracuju, protože se mi nelíbí některé chování.

Update: Připsal jsem defaultní šablonu.

Našli jste v článku chybu? Máte námět na reportáž? Založte mi ticket.