V předchozím článku o serverových ovládacích prvcích jsem ukázal jednoduchý ovládací prvek, který dědil přímo ze třídy „Control“ z jmenného prostoru „System.Web.UI“. V následujících několika řádcích si popíšeme třídy „Control“ a „WebControl“.

Třídu Control je nutné používat v případech, kdy ovládací prvek nebude vykreslovat HTML značky, tedy například v případě ovládacího prvku, který emituje XML či WML značky. U serverových ovládacích prvků, jež vykreslují HTML, je možné dědit přímo z třídy WebControl, kterou naleznete ve jmenném prostoru System.Web.UI.WebControls a která již obsahuje další užitečné vlastnosti a metody, usnadňující programování.

Vlastnosti tříd Control a WebControl

Pro efektivní programování serverových ovládacích prvků je nutné mít přehled o vlastnostech tříd Control a WebControl, aby ze strany programátora nedocházelo k příslovečnému opakovanému vynalézání kola.

Důležité veřejné (public) vlastnosti ve třídě Control:

Název vlastnosti Popis
ClientID Unikátní identifikátor serverového ovládacího prvku, který je v HTML vykreslován jako atribut id.
Controls Kolekce, která obsahuje všechny dětské (child) ovládací prvky. Např. kompozitní serverovový prvek pro správu preferencí uživatele, který bude popsán v dalších článcích, může být interně složen ze dvou textových polí a dvou popisků.
EnableViewState Vlastnost udává, zda prvek ukládá svůj stav do ViewState. Tato vlastnost primárně slouží uživatelům serverových ovládacích prvků, kteří tak mohou snížit množství dat ukládaných na klientský počítač. ViewState je ukládán jako tzv. hidden pole na HTML stránce.
ID ID zadané uživatelem serverového ovládacího prvku. Toto ID je použito jako základ pro generování hodnot vlastností ClientID a UniqueID.
NamingContainer Vlastnost vrátí nejbližší prvek v hierarchii prvků (směrem „nahoru“), který implementuje rozhraní INamingContainer. Rozhraní INamingContainer zaručuje, že každému prvku je přidělen unikátní hierarchický identifikátor, což je důležité zvláště u kompozitních prvků, u nichž je nutné zaručit, že všechny ovládací prvky, ze kterých je prvek složen, mají unikátní ID bez ohledu na počet instancí serverového ovládacího prvku na stránce.
Page Odkaz na stránku, která obsahuje serverový ovládací prvek.
Parent Vrátí rodičovský serverový ovládací prvek. Pokud prvek A patří do kolekce Controls prvku B, potom vlastnost Parent prvku A vrátí prvek B.
UniqueID Unikátní identifikátor serverového ovládacího prvku, který je V HTML vykreslován jako atribut name.
Visible Vlastnost udává, zda je prvek viditelný. Pokud není prvek viditelný, tak se nezobrazí na stránce.

Důležité chráněné (protected) vlastnosti ve třídě Control – chráněné vlastnosti jsou dostupné pouze z odvozených tříd a z třídy, ve které byly deklarovány:

Název vlastnosti Popis
Context Instance třídy HttpContext, která poskytuje přístup k standardním ASP.NET objektům, jakými jsou objekty Session, Request, Response, Application.
ViewState Instance třídy StateBag, kterou si prozatím můžete představit jako kolekci s hodnotami a klíči. Kolekce uchovává aktuální hodnoty vlastností serverového ovládacího prvku a zodpovídá za serializaci hodnot do textového formátu při ukládání stavu na HTML stránku.

Důležité veřejné (public) vlastnosti ve třídě WebControl:

Název vlastnosti Popis
AccessKey Při současném stlačení Alt a písmene přiřazeného do vlastnosti AccessKey prvek získá fokus. Tato vlastnost je na HTML stránce vykreslena jako atribut accesskey.
Attributes Kolekce uživatelem definovaných atributů a jejich hodnot, které jsou vykreslovány na HTML stránku. Více o této vlastnosti si povíme při popisu rozhraní IAttributeAccessor.
BackColor Barva pozadí prvku.
BorderStyle Styl ohraničení prvku (solid, dashed…).
ControlStyle Instance třídy Style z jmenného prostoru System.Web.UI.Controls. Třída Style obsahuje vlastnosti jako BackColor, ForeColor. Třída WebControl vystavuje vlastnosti třídy Style jako své vlastnosti, aby byl objektový model intuitivnější. Třída Style a vytváření rozšířených stylů bude popsáno v dalších článcích.
CssClass Název CSS třídy, která je přiřazena k prvku.
Enabled Vlastnost udává, zda prvek může získat fokus. Na HTML stránce je tato vlastnost v případě hodnoty false vykreslena jako atribut disabled.
Font Font pro vykreslení textu.
ForeColor Barva popředí prvku.
Height Výška prvku.
ToolTip Text, který se zobrazí, pokud je kurzor nad prvkem.
Width Šířka prvku.

Důležité chráněné (protected) vlastnosti ve třídě WebControl:

Název vlastnosti Popis
TagKey Ve vlastnosti je uložen název značky, která reprezentuje serverový ovládací prvek na HTML stránce. Možné hodnoty vlastnosti jsou dány enumerací HtmlTextWriterTag z jmenného prostoru Systém.Web.UI. Standardní hodnota vlastnosti odpovídá značce <span>. Pokud chcete použít značku, která se v enumeraci HtmlTextWriterTag nevyskytuje, musíte přepsat vlastnost TagName.
TagName Ve vlastnosti je uložen název značky, která reprezentuje serverový ovládací prvek na HTML stránce. Vlastnost je typu string, proto můžete použít libovolnou značku, která není definována v enumeraci HtmlTextWriterTag.

Vykreslování serverových ovládacích prvků

V předchozím článku jsme si také ukázali, jak je serverový ovládací prvek vykreslován pomocí metody Render. Vykreslováním, jak jsme řekli, se u serverových ovládacích prvků rozumí emitování značek, kterým „rozumí“ cílová platforma. Nyní si podrobně vysvětlíme, jak je vykreslování implementováno ve třídách Control i WebControl.

Třída Control obsahuje veřejnou metodu RenderControl, která je definována takto:

public void RenderControl (HtmlTextWriter writer)
{
  if (Visible)
  {
    Render(writer);
  }
}

Metoda RenderControl je volána stránkou (objektem z třídy Page) pro každý serverový ovládací prvek na stránce. Metoda má jeden parametr, kterým je objekt z třídy HtmlTextWriter, který obsahuje specializované metody pro vykreslování značek a jejich atributů. Metoda nejdříve zkontroluje, zda má být serverový ovládací prvek viditelný (vlastnost Visible je nastavena na True) a pokud ano, volá metodu Render. Metoda Render vypadá následovně:

protected virtual void Render (HtmlTextWriter writer)
{
  RenderChildren (Writer);
}

Metoda Render je chráněná (protected) a také virtuální. Virtuální znamená, že je možné metodu v odvozených třídách přepsat, čehož jsme využili při psaní našeho prvního serverového ovládacího prvku. Standardně metoda Render volá metodu RenderChildren:

protected virtual void RenderChildren (HtmlTextWriter writer)
{
  foreach (Control c in Controls)
  {
    c.RenderControl (writer);
  }
}

Metoda prochází kolekci Controls, která obsahuje dětské (child) prvky a volá jejich metodu RenderControl. Opět se jedná o virtuální metodu, takže je ji možné přepsat.

Ve třídě WebControl je přepsána metoda Render a vypadá takto:

protected override void Render (HtmlTextWriter writer)
{
  RenderBeginTag (writer);
  RenderContents (writer);
  RenderEndTag (writer);
}

Nejprve je volána metoda RenderBeginTag. Ta je definována následovně:

public virtual void RenderBeginTag (HtmlTextWriter writer)
{
  AddAtributesToRender (writer);
  HtmlTextWriter tagKey = TagKey;
  if (tagKey != HtmlTextWriterTag.Unknown)
  {
    writer.RenderBeginTag(tagKey);
  }
  else
  {
    writer.RenderBeginTag(TagName);
  }
}

Nejprve je volána metoda AddAtributesToRender, jejíž výpis nebudu uvádět. Je třeba pouze vědět, že tato metoda se stará například o vykreslení atributu id a že v případě jejího přepsání v odvozené třídě musíte vždy zavolat metodu AddAtributesToRender bázové třídy, pokud chcete, aby byly všechny atributy vykresleny! Dále je vykreslena počáteční značka prvku, a to značka ve vlastnosti TagKey, pokud vlastnost TagKey nemá hodnotu HtmlTextWriterTag.Unknown (tehdy je vykreslena značka ve vlastnosti TagName).

Vraťme se ale k metodě Render, ve které je po metodě RenderBeginTag volána metoda RenderContents, jež vypadá takto:

protected virtual void RenderContents (HtmlTextWriter writer)
{
  base.Render (writer)
}

Metoda RenderContens standardně zavolá metodu Render ze třídy Control, která, jak bylo popsáno výše, vykreslí všechny prvky v kolekci Controls. Pokud budete dědit z třídy WebControl, přepíšete většinou metodu RenderContents a nikoli metodu Render, kterou budete přepisovat pouze tehdy, pokud dědíte přímo ze třídy Control. Dají se nalézt i výjimky z tohoto pravidla, ale ty pro nás prozatím nejsou příliš důležité.

Jako poslední v metodě Render je volána metoda RenderEndTag, která vykreslí koncovou značku serverového ovládacího prvku:

public virtual void RenderEndTag (HtmlTextWriter writer)
{
  HtmlTextWriter tagKey = TagKey
  if (tagKey ! = HtmlTextWriterTag.Unknown)
  {
    writer.RenderEndTag(tagKey);
  }
  else
  {
    writer.RenderEndTag(TagName);
  }
}

Bez příkladu by to nešlo

Na konec opět jednoduchý příklad (zdrojový kód). Vytvoříme serverový ovládací prvek tlačítko, který bude (nyní ještě poněkud nedokonale) napodobovat tlačítko ze standardně dodávaných ovládacích prvků v ASP.NET. V dalších článcích jej rozšíříme o podporu serverových událostí a zpracování dat po odeslání formuláře (postback). Zde budou vysvětleny pouze zajímavé části kódu.

Nejprve vytvoříme novou třídu, která bude potomkem třídy WebControl:

[DefaultProperty(„Text“),
[ToolboxData(„<{0}:WebButton runat=server></{0}:WebButton>“)]
public class WebButton : System.Web.UI.WebControls.WebControl
{

}

Třída WebButton je dekorována dvěma metaatributy, které využívají RAD designéři. Metaatribut DefaultProperty udává, jaká vlastnost je výchozí pro serverový ovládací prvek. V našem případě se jedná o vlastnost Text, jejíž hodnota bude vykreslena jako textový obsah HTML značky <button>. Metaatribut ToolboxData říká, jaká značka bude vytvořena po přetažení serverového ovládacího prvku z panelu nástrojů (toolboxu). Jeho význam byl již podrobně vysvětlen v předchozím článku.

Následující výpis ukazuje definici vlastnosti Text:

public class WebButton : System.Web.UI.WebControls.WebControl
{
  …
  [Bindable(true),
  Category(„Appearance“),
  DefaultValue(„“)]
  public string Text
  {
    get
    {
      // Získání hodnoty z ViewState
      string vtext = (string) ViewState[„Text“];
      // Pokud hodnota nebyla uložena do ViewState, vrať prázdný řetězec.
      if (vtext == null)
        return String.Empty;
      // Jinak vrať hodnotu z ViewState
      else
        return vtext;
     }
    set
    {
        // Ulož novou hodnotu do ViewState
        ViewState[„Text“] = value;
    }
  }
  …
}

Vlastnost Text je také dekorována metaatributy. Metaatribut Bindable s hodnotou True RAD designéry informuje, že vlastnost je možné svázat s datovým zdrojem. Metaatribut Category udává, v jaké kategorii na stránce vlastností prvku se vlastnost Text zobrazí. Metaatribut DefaultValue, jak již naznačuje jméno, určuje výchozí hodnotu vlastnosti. Zajímavé je ukládání a získání hodnoty vlastnosti, kdy namísto použití privátního člena třídy, je hodnota vlastnosti perzistována ve ViewState. Mechanismus ukládaní do ViewState bude ještě podrobně vysvětlen v dalších článcích, zde jen připomínám, že ViewState nám dovoluje ukládat a rekonstruovat hodnoty vlastností prvků mezi odesláními formuláře (tzv. „postbacky“).

Protože náš serverový ovládací prvek má být vykreslen pomocí HTML značky <button>, přepíšeme vlastnost TagKey tak, aby vracela prvek Button z enumerace HtmlTextWriterTag:

public class WebButton : System.Web.UI.WebControls.WebControl
{
  …
  /// <summary>
  /// Přepíšeme vlastnost TagKey, protože chceme vykreslovat tlačítko
  /// </summary>
  protected override HtmlTextWriterTag TagKey
  {
    get
    {
      return HtmlTextWriterTag.Button;
    }
  }
  …
}

Dále jsme přepsali metodu AddAttributesToRender, ve které tlačítku přidáváme obsluhu události onclick. Tato událost je vyvolána pouze na klientské straně. Jak mapovat klientské události na serverové události se dozvíte v příštím článku. Také jsme přidali atribut name, který odpovídá vlastnosti UniqueID serverového ovládacího prvku. Všimněte si, že po přidání vlastního atributu prvek volá metodu AddAttributesToRender bázové třídy.

public class WebButton : System.Web.UI.WebControls.WebControl
{
  …
  /// <summary>
  /// Přidáme atribut onclick a name pro demonstraci možností metody AddAttributesToRender
  /// </summary>
  /// <param name=“writer“>Instance třídy <see cref=“HtmlTextWriter“/>, která je použita k vykreslení prvku </param>
  protected override void AddAttributesToRender (HtmlTextWriter writer)
  {
    // Přidání atributu onclick
    writer.AddAttribute(HtmlTextWriterAttribute.Onclick, „javascript:alert(‚Tlačítko ‚ + this.id + ‚ stisknuto!‘);“);
    // Přidání atributu name
    writer.AddAttribute(HtmlTextWriterAttribute.Name, this.UniqueID);
    // Volání metody AddAttributesToRender z bázové třídy, aby se vykreslily správně všechny atributy zděděné ze třídy WebControl
    base.AddAttributesToRender(writer);
    }
}

Dále přepíšeme metodu RenderContents, která vykreslí vlastnost Text:

public class WebButton : System.Web.UI.WebControls.WebControl
{
  …
  /// <summary>
  /// V metodě RenderContents vypíšeme obsah prvku. V našem případě pouze vlastnost <see cref=“Text“/>.
  /// </summary>
  /// <param name=“writer“></param>
  protected override void RenderContents (HtmlTextWriter writer)
  {
    writer.Write(Text);
  }
  …
}

Další serverový ovládací prvek, respektive jeho základ, je vytvořen.

Žádný příspěvek v diskuzi

Odpovědět