Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial

Estendere un controllo TextBox in ASP.NET

Analizziamo le modalità con cui è possibile estendere le funzionalità di base dei controlli server
Analizziamo le modalità con cui è possibile estendere le funzionalità di base dei controlli server
Link copiato negli appunti

ASP.NET fornisce allo sviluppatore di applicazioni web una serie di controlli server (detti anche comandi server) utilizzabili all'interno delle pagine aspx. In questo articolo analizzeremo le modalità tramite cui è possibile estendere le funzionalità di base dei controlli server ASP.NET. Per una adeguata introduzione al mondo dei controlli server in ASP.NET potete leggere la guida pubblicata su Html.it.

Creare un nuovo controllo server

Supponiamo di voler creare una casella di testo speciale. Questa textbox sarà visualizzata sul browser in modo differente in base al valore dell'attributo ReadOnly:

  • Se è uguale a false:  verrà visualizzata la tipica casella di testo (grazie al tag HTML <input>). Inoltre verrà aggiunto un controllo di validazione per impedire all'utente di immettere di valori nulli o inconsistenti all'interno della textbox.
  • Se è uguale a true: verrà visualizzata invece una semplice etichetta (tramite il tag HTML <span/>) con il contenuto testuale.

Ecco due screenshot che illustrano il risultato finale:

Screenshot
Screenshot

Tutto è pronto, ora non rimane che metterci al lavoro!

Ereditare le funzionalità di base del controllo da una TextBox

Grazie alla natura orientata agli oggetti (Object Oriented o OO) del framework .NET estendere le funzionalità di un controllo esistente è un gioco da ragazzi. Come tutti i linguaggi OO anche C# supporta il concetto di ereditarietà.  L'ereditarietà permette di derivare una nuova classe partendo da una classe padre. Questo processo implica che la nuova classe (detta derivata) conservi tutti i membri pubblici e privati della classe padre. In soldoni questo un grosso vantaggio; oltre ad avere tutte le funzionalità della classe padre senza scrivere una sola riga di codice, potremo anche potenziare la classe derivata con le nuove funzionalità che ci occorrono. Vediamo un esempio ci come usare l'ereditarietà in C#:

public class ControlloDerivato : ControlloPadre {
      //Codice che specializza il controllo...
}

Per il controllo che dobbiamo sviluppare a noi fa comodo derivare le funzionalità di base dal classico controllo TextBox già presente in ASP.NET:

public class MyTextBox: System.Web.UI.WebControls.TextBox {
      //Codice che specializza il controllo...
}

A questo punto abbiamo una creato nuova classe: MyTextBox. Questa classe rappresenta il nostro nuovo controllo, ora non rimane che aggiungere le altre funzionalità richieste.

Aggiungere un controllo RequiredFieldValidator

Uno dei compiti assegnati al controllo è: validare in modo automatico la presenza di un valore nella casella di testo. Per raggiungere questo obiettivo ci serviamo di un controllo server già presente nel framework .NET che fa al caso nostro: RequiredFieldValidator.

public class MyTextBox: System.Web.UI.WebControls.TextBox {
      //Aggiungo il controllo per validare il testo immesso

      //per ora ci basta sapere questo, dopo vedremo
le modalità
      //corrette per aggiungere il controllo
      private  RequiredFieldValidator req = new
RequiredFieldValidator();
}

Qui non abbiamo ereditato nulla da altre classi del framework .NET, ma semplicemente aggiunto un'istanza del controllo RequiredFieldValidator all'interno della classe MyTextBox.

Modificare il ciclo di vita di un controllo

I controlli server che popolano il mondo ASP.NET possiedono un ciclo di esecuzione chiamato CEL (Control Execution Lifecycle) che prende vita ad ogni specifica richiesta web da parte dell'utente. Il CEL di un controllo è composto da diversi fasi, che possiamo immaginare come una sequenza di eventi:

  1. Initialize
  2. Load view state
  3. Process postback data
  4. Load
  5. Send postback change notifications
  6. Handle postback events
  7. Prerender
  8. Save state
  9. Render
  10. Dispose
  11. Unload>

Per ognuna di queste fasi è possibile riscrivere (override nel linguaggio OO)  le operazioni che avvengono al loro interno allo scopo di specializzare il comportamento del controllo. Nel nostro caso dovremo intervenire su due fasi: Initialize e Render. Ricordiamoci due cose importanti:

  1. non tutte le fasi possono essere sovrascritte
  2. ad ogni fase corrisponde un evento il quale è richiamato da un metodo corrispondente

Gestire lo stato utilizzando ViewState

Usando ViewState ci assicuriamo la persistenza delle informazioni legate ai controlli della pagina durante il continuo scambio Server-Client. Questa soluzione consente di trasferire lo stato dei controlli dal Server al Client e viceversa senza perdita di informazioni. Ciò significa che quando il Server leggerà il ViewState di una pagina sarà in grado di ripristinare, ad esempio per il nostro controllo, il valore assegnato dall'utente alla proprietà MyErrorMessagge.

public string MyErrorMessage
{
      get{return ((string)ViewState["MyErrorMessage"]);}
      set{ViewState["MyErrorMessage"] = value;}
}

Con l'obiettivo di non perdere informazioni sui controlli durante il PostBack, implementeremo tutte le proprietà pubbliche del controllo con l'oggetto ViewState e non con variabili private.

public string LabelCSSClass
{
      get{return ((string)ViewState["LabelCSSClass"]);}
      set{ViewState["LabelCSSClass"] = value;}
}

Rivediamo la fase Initialize

Questa fase si occupa di inizializzare tutti i membri del controllo e di creare tutti gli oggetti in esso contenuti. Questo è il punto giusto dove creare un'istanza del controllo ASP.NET RequiredFieldValidator ed aggiungerla alla collezione dei controlli della pagina web corrente:

protected override void OnInit(EventArgs e)
{
      req = new RequiredFieldValidator();
      req.ID = String.Format("req{0}",this.ID);
      req.ControlToValidate = this.ID;
      req.EnableClientScript = false;
      req.ErrorMessage = this.MyErrorMessage;
      Controls.Add(req);
}

Rivediamo la fase Render()

Questa fase è fondamentale per gestire l'output sul browser web del controllo. Grazie all'oggetto HtmlTextWriter (passato come parametro al metodo Render) è possibile manipolare in modo diretto il markup del controllo. Se l'attributo readonly è uguale a true generiamo una semplice etichetta (tramite il tag <span>). Il testo dell'etichetta viene recuperato dalla proprietà Text mentre  l'eventuale classe da abbinare all'etichetta viene recuperata dalla proprietà LabelCSSClass.

protected override void Render(System.Web.UI.HtmlTextWriter writer)
{
      if(this.ReadOnly)
      {
      //Scrivo una etichetta tramite il tag SPAN
      writer.Write(@"<span class=""{0}"">{1}</span>",

      this.LabelCSSClass, this.Text);
      }    
      else
      {
     //Scrivo la classica casella di testo tramite il tag
INPUT
     base.Render(writer);
    //Scrivo il markup del controllo RequiredFieldValidator
    req.RenderControl(writer);
      }
}

Al contrario, se l'attributo readonly è uguale a false, lasciamo che il metodo Render produca il markup tipico di una textbox (tramite il tag <input>).

Compilare e registrare il controllo

Bene, tutto è pronto! Finalmente possiamo compilare il controllo all'interno di un assembly (una dll nel nostro caso). Usando la cara vecchia finestrella tipo DOS:

csc /out:lm.html.webcontrols.dll /target:library /r:system.dll MyTextBox.cs

Ora che l'assembly è stato creato correttamente, non ci resta che scaricarlo nella directory bin dell'applicazione web e tramite la direttiva Register renderlo disponibile all'uso all'interno della pagina web interessata:

<%@ Register TagPrefix="myctrl" Namespace="WebLabs.Html.it.MyControls" Assembly="lm.html.webcontrols" %>

Per utilizzare il controllo nella pagina non dovremo fare altro che dichiarare il TAG myctrl all'interno della pagina aspx:

<myctrl:MyTextBox runat="server" id="MyClassicTextBox" MyErrorMessage="Il campo è obbligatorio!">Testo Editabile!</myctrl:MyTextBox>

Basta settare l'attributo readonly uguale a true e la textbox magicamente si trasforma in un etichetta di testo! (fate questa modifica e ricaricate la pagina web...)

<myctrl:MyTextBox runat="server" id="MyClassicTextBox" ReadOnly="True">Testo NON più Editabile!</myctrl:MyTextBox>

Conclusione

In questo articolo abbiamo visto come in pochi passi, grazie alle tecniche OO, sia possibile creare un controllo lato server in ASP.NET:

  1. Capire le funzionalità che deve avere il nuovo controllo.
  2. Scegliere un controllo padre già esistente  (la TextBox nel nostro caso) che abbia caratteristiche simili a quelle che vogliamo ritrovare nel nuovo controllo.
  3. Utilizzare l'ereditarietà per derivare una nuova classe partendo dal controllo padre.
  4. Aggiungere il controllo RequiredFieldValidator per poter validare il testo immesso.
  5. Creare le proprietà pubbliche MyErrorMessage e LabelCSSClass all'interno di MyTextBox.
  6. Assicurarci che i valori di queste proprietà siano recuperati o salvati tramite il ViewState. In questo modo ci garantiamo una corretta gestione della persistenza delle informazioni attraverso le varie richieste tra Server e Client.
  7. Sovrascrivere le fasi del CEL utili per personalizzare il comportamento del controllo:
    1. OnInit, per aggiungere dinamicamente (a run-time)  il controllo RequiredFieldValidator.
    2. Render, per generare un markup differenziato in base al valore dell'attributo ReadOnly.
  8. Compilare il codice del nuovo controllo.
  9. Referenziare il controllo all'interno della form web in cui intendiamo utilizzarlo.

Una demo dell'applicazione la potete trovare qui, allegato all'articolo invece troverete uno zip con il codice sorgente.

Ti consigliamo anche