70-562: Working with Custom Web Server Controls

Artykuł pochodzi w serii przygotowań do egzaminu 70-562 ASP.NET.

Tworzenie własnej Web Server Control

Niestandardowa kontrolka serwerowa może dziedziczyć z kontrolki WebServer. Musi zawierać kod który pozwoli ją renderować bądź może podziedziczyć to z innej kontrolki. Zazwyczaj są dwa podejścia do tworzenia takich kontrolek. Pierwsze z nich to podziedziczyć po WebControl która da nam podstawowy zestaw funkcjonalności. Obejmuje to również takie właściwości jak np. BackColor, ForeColor, Font, Height, i Width. Drugi częściej stosowany sposób to podziedziczyć po istniejącej już kontrolce i rozwijać jej funkcjonalność. Niezależnie od podejścia należy wziąć pod uwagę wielokrotne/ponowne użycie kontrolki. Jeśli nasza kontrolka będzie wykorzystywana w wielu witrynach należałoby ją utworzyć jako osobną .dll .

Dziedziczenie z istniejącej kontrolki

Jak przed chwilą wspomniałem typowym sposobem na tworzenie własnej kontrolki jest podziedziczenie po istniejącej już i rozszerzenie jej funkcjonalności. Powiedzmy, że chcemy stworzyć kontrolkę która będzie nam udostępniała TextBox i będziemy mogli ustawiać szerokość. W kodzie byśmy realizowali to następująco:

   1: //C#
   2: using System;
   3: using System.Web.UI;
   4: using System.Web.UI.WebControls;
   5: public class LabeledTextBox : TextBox
   6: {
   7: public string PromptText { get; set; }
   8: public int PromptWidth { get; set; }
   9: protected override void Render(HtmlTextWriter writer)
  10: {
  11: writer.Write(
  12: @"<span style="”display:inline-block;width:{0}px”">{1}&nbsp;</span>",
  13: PromptWidth, PromptText);
  14: base.Render(writer);
  15: }
  16: }

 

Potem żeby wykorzystać naszą kontrolkę postępujemy tak jak poniżej:

   1: //C#
   2: protected void Page_Init(object sender, EventArgs e)
   3: {
   4: int width = 150;
   5: MyUserControls.LabeledTextBox prompt1 = new
   6: MyUserControls.LabeledTextBox();
   7: prompt1.PromptText = “Enter Name:";
   8: prompt1.PromptWidth = width;
   9: form1.Controls.Add(prompt1);
  10: LiteralControl br = new LiteralControl("<br />");
  11: form1.Controls.Add(br);
  12: MyUserControls.LabeledTextBox prompt2 = new
  13: MyUserControls.LabeledTextBox();
  14: prompt2.PromptText = “Enter Address:";
  15: prompt2.PromptWidth = width;
  16: form1.Controls.Add(prompt2);
  17: }

 

W magiczny sposób otrzymamy:

11

Dziedziczenie bezpośrednio z klasy WebControl

Tutaj musimy pamiętać aby koniecznie aby nadpisać metodę Render. Na potrzeby tego działu powiedzmy, że chcemy mieć kontrolkę która wyświetla logo oraz nazwę firmy. Realizacje tego przedsięwzięcia ukazuje poniższy kod:

   1: //C#
   2: using System;
   3: using System.Web.UI;
   4: using System.Web.UI.WebControls;
   5: public class LogoControl : WebControl
   6: {
   7: public LogoControl()
   8: {
   9: }
  10: public string LogoUrl
  11: {
  12: get { return _logoUrl; }
  13: set { _logoUrl = value; }
  14: }
  15: private string _logoUrl;
  16: public string CompanyName
  17: {
  18: get { return _companyName; }
  19: set { _companyName = value; }
  20: }
  21: private string _companyName;
  22: protected override void Render(HtmlTextWriter writer)
  23: {
  24: writer.WriteFullBeginTag(“div”);
  25: writer.Write(@"<img src=""{0}"" /><br />", LogoUrl);
  26: writer.Write(CompanyName + "<br />");
  27: writer.WriteEndTag(“div”);
  28: }
  29: }

 

Dodawanie kontrolki do ToolBox’a

W poprzednim przykładzie dodanie kontrolki odbywało się dynamicznie co odpowiednio zapisaliśmy w kodzie. My jednak jesteśmy przyzwyczajeni, że mamy zbiór gotowych kontrolek, przeciągamy je na formatkę i gotowe ;) Nic nie stoi na przeszkodzie aby dodać naszą kontrolkę do ToolBox’a . Jednak aby można było to zrobić nasza kontrolka musi być w dll. Kiedy mam tak przygotowaną kontrolkę klikamy w toolboxie PPM i wybieramy Choose Items i dalej jasne ;) Powiedzmy, że mieliśmy wcześniej przygotowaną dll MyUserControls, to po dodaniu jej widzimy zawarte w niej i wcześniej opisywane kontrolki:

22

Widzimy, że obok nazwy mamy dodaną jakąś domyślną ikonkę. Nic nie stoi na przeszkodzie aby ustawić własną. Do tego należy wykorzystać atrybut ToolboxBitmap z przestrzeni nazw System.Drawing . Ten atrybut określa mapę bitową 16 × 16 pikseli.

   1: //C#
   2: [ToolboxBitmap(typeof(LabeledTextBox),
   3: “MyUserControls.LabeledTextBox.bmp”)]
   4: public class LabeledTextBox : TextBox

 

Aby jeszcze dopracować naszą kontrolkę przydałaby sie domyślna właściwość. Tą możemy określić atrybutem DefaultProperty z przestrzeni nazw System.ComponentModel .

   1: //C#
   2: [DefaultProperty(“PromptText”)]
   3: public class LabeledTextBox : TextBox

Tworzenie własnego wyglądu dla kontrolki

Naturalnie kontrolki z ToolBoxa mają już jakiś domyślny wygląd. Możemy podejrzeć je w Design View i pracować z nimi za pomocą okna Properties. Może zaistnieć naturalna potrzeba, że chcielibyśmy zmienić domyślny wygląd naszej kontrolki, ba nawet może się zdarzyć, że musimy pewne specyficzne rzeczy poustawiać  żeby kontrolka była widoczna.

Aby to zrobić musimy zacząć od dodania do naszej kontrolki referencji do System.Design.dll . Następnie tworzymy nową klasę która dziedziczy po klasie ControlDesigner. W niej nadpisujemy metodę GetDesignTimeHtml w której jest HTML użyty później jako wygląd naszej kontrolki. Jako przykład, pomyślmy, że mamy kontrolkę która jest “pochodną” LabelTextBoxa i przypomina nam o ustawieniu tekstu do niej. Jeśli  jest ustawiony “PromptText” to zostanie wyświetlony domyślny (bazowy) widok. Oto kod:

   1: namespace MyUserControls
   2: {
   3: public class LabeledTextBoxDesigner : ControlDesigner
   4: {
   5: private LabeledTextBox _labeledTextBoxControl;
   6: public override string GetDesignTimeHtml()
   7: {
   8: if (_labeledTextBoxControl.PromptText.Trim().Length == 0)
   9: return "<div style='color: Gray'>[Define PromptText]</div>";
  10: else
  11: return base.GetDesignTimeHtml();
  12: }
  13: public override void Initialize(IComponent component)
  14: {
  15: _labeledTextBoxControl = (LabeledTextBox)component;
  16: base.Initialize(component);
  17: return;
  18: }
  19: }
  20: }

Następnie musimy dodać do naszej klasy z kontrolką atrybut DesignerAttribute :

   1: //C#
   2: [Designer(“MyUserControls.LabeledTextBoxDesigner, MyUserControls”)]
   3: public class LabeledTextBox : TextBox

I teraz efekt pracy, jeśli PromptyText nie jest ustawiony kontrolka będzie wyglądała następująco:

33

Tworzenie kontrolki złożonej

Możemy stworzyć własną tkz. kontrolkę złożona. Aby to uczynić musimy stworzyć klasę która podziedziczy po klasie CompositeControl. W nowej klasie konieczne jest przysłonięcie metody CreateChildControls. W niej m.in ustawiamy wszystkie potrzebne właściwości. Ponieważ każda “child controls” wie jak radzić sobie z takimi mechanizmami jak ViewState, PostBack my oszczędzamy sobie czasu i nerwy na pisanie dodatkowego kodu. Jak zrobić naszą własną kontrolkę gdzie mielibyśmy nazwę użytkownika, hasło oraz przycisk Submit? Kod oraz wygląd przykładowy poniżej:

44

   1: //C#
   2: using System;
   3: using System.ComponentModel;
   4: using System.Web.UI;
   5: using System.Web.UI.WebControls;
   6: using System.Drawing;
   7: public class UserPasswordControl : CompositeControl
   8: {
   9: public event System.EventHandler Submitted;
  10: public string UserName
  11: {
  12: get
  13: {
  14: TextBox txt = (TextBox)FindControl(“UserName”);
  15: return txt.Text;
  16: }
  17: set
  18: {
  19: TextBox txt = (TextBox)FindControl(“UserName”);
  20: txt.Text = value;
  21: }
  22: }
  23: public string Password
  24: {
  25: get
  26: {
  27: TextBox pwd = (TextBox)FindControl(“Password”);
  28: return pwd.Text;
  29: }
  30: set
  31: {
  32: TextBox pwd = (TextBox)FindControl(“Password”);
  33: pwd.Text = value;
  34: }
  35: }
  36: protected override void CreateChildControls()
  37: {
  38: Panel pnl = new Panel();
  39: TextBox txtUserName = new TextBox();
  40: TextBox txtPassword = new TextBox();
  41: Button btnSubmit = new Button();
  42: btnSubmit.Click += new EventHandler(btnSubmit_Click);
  43: //start control buildup
  44: Controls.Add(pnl);
  45: //add user name row
  46: pnl.Controls.Add(new LiteralControl("<table><tr><td>"));
  47: pnl.Controls.Add(new LiteralControl(“User Name:"));
  48: pnl.Controls.Add(new LiteralControl("</td><td>"));
  49: pnl.Controls.Add(txtUserName);
  50: pnl.Controls.Add(new LiteralControl("</td></tr>"));
  51: //add password row
  52: pnl.Controls.Add(new LiteralControl("<tr><td>"));
  53: pnl.Controls.Add(new LiteralControl(“Password:"));
  54: pnl.Controls.Add(new LiteralControl("</td><td>"));
  55: pnl.Controls.Add(txtPassword);
  56: pnl.Controls.Add(new LiteralControl("</td></tr>"));
  57: //add submit button row
  58: pnl.Controls.Add(new LiteralControl(
  59: @"<tr><td colspan="”2”" align="”center”" >"));
  60: pnl.Controls.Add(btnSubmit);
  61: pnl.Controls.Add(new LiteralControl("</td></tr></table>"));
  62: //set up control properties
  63: pnl.Style.Add(“background-color”, “silver”);
  64: pnl.Style.Add(“width”, “275px”);
  65: txtUserName.ID = “UserName”;
  66: txtUserName.Style.Add(“width”, “170px”);
  67: txtPassword.ID = “Password”;
  68: txtPassword.TextMode = TextBoxMode.Password;
  69: txtPassword.Style.Add(“width”, “170px”);
  70: btnSubmit.Text = “Submit”;
  71: }
  72: void btnSubmit_Click(object sender, EventArgs e)
  73: {
  74: if (Submitted != null) Submitted(this, e);
  75: }
  76: }
  77: //C#
  78: using System;
  79: using System.Web.UI;
  80: using System.Web.UI.WebControls;
  81: public partial class UserPasswordControlTest : System.Web.UI.Page
  82: {
  83: protected void Page_Init(object sender, EventArgs e)
  84: {
  85: UserPasswordControl p = new MyUserControls.UserPasswordControl();
  86: p.Style.Add(“position”, “absolute”);
  87: p.Style.Add(“left”, “25px”);
  88: p.Style.Add(“top”, “50px”);
  89: form1.Controls.Add(p);
  90: p.Submitted += new EventHandler(p_Submitted);
  91: }
  92: void p_Submitted(object sender, EventArgs e)
  93: {
  94: UserPasswordControl p = (UserPasswordControl)sender;
  95: Response.Write(“User: " + p.UserName + " Pass: " + p.Password);
  96: }
  97: }

To tyle na dzisiaj. Myślę, że tworzenie własnych kontrolek to bardzo ciekawy temat. W tym artykule są oczywiście podstawy podstaw ale warto rozszerzyć wiedzę własną w tym zakresie czego sobie i Wam życzę ;) Miłego weekendu!

Tagi: , , ,

Add comment




  Country flag
biuquote
  • Comment
  • Preview
Loading


Eastgroup.pl na facebooku