Microsoft Asp.Net introduce tra le tante novità l'utilizzo dei Web User Control (User Control nel testo di questo articolo). Un Web User Control è simile ad una normale Web Form e può contenere anch'esso uno dei tanti oggetti che Asp.Net ci mette a disposizione (datagrid, dropdownlist, panel, etc.). La sua utilità, è quella di poter essere caricato in una Web Form similmente a come si faceva in Asp classico con i file inclusi. Per chi li ha usati, in Asp si potevano creare dei file esterni contenenti HTML e/o script Asp e in questo modo si riusciva a "riciclare" più facilmente parti di codice uguali includendo lo stesso file in più pagine. I Web User Control, in sintesi, svolgono la stessa funzione.
Con uno User Control, insomma, possiamo riutilizzare facilmente il codice in
esso contenuto. Per nostra fortuna, usare uno User Control o una normale Web Form è pressocché uguale, quindi non dobbiamo reimparare nulla. Possiamo trascinare in fase di design sulla form dello User Control tutti i server control dalla toolbox di cui abbiamo bisogno e abbiamo il codebehind che contiene il codice così come con una normale Web Form.
A differenza delle normali Web Form che hanno l'estensione .aspx, i Web User Control hanno l'estensione .ascx. Dopo averlo creato, per utilizzare un Web User Control, è obbligatorio caricarlo in una Web Form.
Per creare uno User Control, si può cliccare con il tasto destro sul
progetto e aggiungere un nuovo elemento. Selezionate quindi la voce "Controllo utente Web" o "Web User Control":
Possiamo inserire uno User Control in una Web Form, in maniera dichiarativa:
<%@ Register tagprefix="DeRossi" Tagname="Login" Src="Login.ascx" %>
Nel codice della pagina aspx per visualizzare lo User Control avremo:
<DeRossi:Login id="mioLogin" runat="server"></DeRossi:Login>
Possiamo farlo anche in maniera programmatica, scrivendo direttamente il codice nella pagina di codebehind. Per chi non lo sapesse, in sintesi, il codebehind è una pagina con estensione .vb o .cs che contiene tutto il codice di programmazione legato in vario modo alla relativa pagina .aspx e permette così una migliore separazione tra HTML e codice.
Nell'esempio seguente ph è un oggetto di tipo placeholder presente sulla Web Form che usiamo come contenitore. Ricordiamo che un placeholder è uno dei Server Control messi a disposizione da Asp.Net e ci è utile come contenitore di altri server control:
Vb.Net
Dim mioLogin As Login = Me.LoadControl("Login.ascx")
ph.Controls.Add(mioLogin)
C#
Login mioLogin = (Login)this.LoadControl("Login.ascx");
ph.Controls.Add(mioLogin);
In questa maniera mioLogin è già un Web User Control di “tipo” Login. Se invece volete caricare genericamente un Web User Control, ad esempio nel caso abbiate più User Control nel vostro progetto da assegnare alla stessa variabile, potete anche scrivere:
Vb.Net
Dim mioLogin As Control = Me.LoadControl("Login.ascx")
C#
Control mioLogin = this.LoadControl("Login.ascx");
Ricordandovi però che se volete accedere ai membri (es. una proprietà pubblica “Titolo” che avete creato voi) dovrete provvedere al cast esplicito dello User Control:
Vb.Net
Ctype(mioLogin, Login).Titolo = “"Login applicazione"”
C#
((Login)mioLogin).Titolo = "Login applicazione";
Possiamo facilmente caricare un Web User Control diverso a seconda della scelta dell'utente. Se ad esempio abbiamo sulla pagina aspx un menu che presenta delle voci che passano alla stessa pagina (es. un parametro index.aspx?action=Principale) e sempre sulla stessa pagina un placeholder di nome ph possiamo scrivere una sub routine simile alla seguente e richiamarla nel Page_Load della pagina aspx:
Vb.Net
Private Sub loadUserControl()
Dim ucLoad As Control
Select Case Request("action")
Case "Principale "
ucLoad = Me.LoadControl("principale.ascx")
ph.Controls.Add(ucLoad)
Case "Ricerche"
ucLoad = Me.LoadControl("ricerche.ascx")
ph.Controls.Add(ucLoad)
End Select
End Sub
C#
private void loadUserControl()
{
Control ucLoad = null;
switch(Request["action"])
{
case "Principale":
ucLoad = this.LoadControl("principale.ascx");
ph.Controls.Add(ucLoad);
break;
case "Ricerche":
ucLoad = this.LoadControl("ricerche.ascx");
ph.Controls.Add(ucLoad);
break;
}
}
L'applicazione di esempio
Nell'applicazione di esempio (disponibile per il download) in Vb.Net, troverete un semplice progetto Web contenente una pagina Default.aspx e uno User Control Clienti.aspx con una datagrid che visualizza l'elenco di record filtrati per paese di provenienza. L'applicazione fa uso del database Northwind il cui percorso nel vostro computer può essere impostato nel file Web.config.
È possibile definire dalla pagina aspx il paese di provenienza e caricare
a runtime lo User Control impostandone la proprietà paese:
Interazione della pagina aspx con un Web User Control
Se c'è’la necessità di leggere un valore presente in un
controllo di un Web User Control dalla pagina che lo ospita potete farlo così. Ecco l'esempio di lettura dalla pagina aspx di una dropdownlist di nome ddlTipo presente nello User Control mioLogin:
Vb.Net
Dim m_tipo As String = CType(mioLogin.FindControl("ddlTipo"), DropDownList).SelectedValue
C#
String m_tipo = ((DropDownList)mioLogin.FindControl("ddlTipo")).SelectedValue;
È anche possibile far dialogare la Web Form che ospita lo User Control
attraverso l'esposizione di membri pubblici come ad esempio delle proprietà che potremo valorizzare dalla Web Form ospitante al momento del caricamento dello User Control. Se ad esempio il nostro User Control visualizza un elenco di record e abbiamo la necessità di impostare un filtro su questi record, come ad esempio il paese di provenienza dei clienti, allora potremo inserire nello User Control una proprietà pubblica chiamata Paese. Dalla pagina aspx, per modificare la proprietà paese presente nello User Control possiamo trattare lo User Control come faremmo con una qualsiasi classe del nostro progetto:
Vb.Net
Dim uc As Clienti = Me.LoadControl("Clienti.ascx")
uc.Paese = "Italia"
ph.Controls.Add(uc)
C#
Clienti uc = ((Clienti)this.LoadControl("Clienti.ascx"));
uc.Paese = "Italia";
ph.Controls.Add(uc);
Evento Page_Load e Page_PreRender
A volte può essere utile decidere il momento in cui caricare e quindi
eseguire il Web User Control e il codice in esso contenuto rispetto al caricamento della pagina aspx che lo ospita. È ad esempio possibile eseguire prima il codice dello Web User Control se vogliamo decidere come renderizzare la pagina aspx che lo ospita spostando il suo caricamento dall'evento Page_Load all'evento Page_PreRender della pagina aspx.
Mettiamo di voler usare un Web User Control per l'header di una pagina aspx.
Vogliamo visualizzare un controllo panel presente nella pagina aspx ospitante
solo se una variabile di sessione valorizzata nello User Control è true. Nell'evento Page_Load del Web User Control header.ascx abbiamo il codice:
Vb.Net
Session("header") = True
C#
Session["header"] = true;
mentre nell'evento Page_Load della pagina aspx mettiamo il codice:
Vb.Net
Dim uc As Control = Me.LoadControl("header.ascx")
ph.Controls.Add(uc) ‘'ph è un controllo di tipo placeholder presente sulla pagina
If Session("header") = True Then
panel1.Visible = True
Else
panel1.Visible = False
End If
C#
Control uc = this.LoadControl("header.ascx");
ph.Controls.Add(uc); // ph è un controllo di tipo placeholder presente
sulla pagina
if (((bool)Session["header"]) == true)
Panel1.Visible = true;
else Panel1.Visible = false;
Se eseguiamo la pagina aspx, noteremo come il panel1 non sarà visibile. Se invece spostiamo il codice su indicato nell'evento Page_PreRender della pagina aspx il panel1 sarà correttamente visualizzato al primo caricamento.
Utilizzare il caching con un Web User Control
È possibile effettuare il caching solo di uno User Control e non dell'intera Web Form. Questa tecnica è chiamata fragment caching. Inserendo nella sezione design del Web User Control una direttiva come questa:
<% @OutputCache duration="100" varybyparam="none" %>
facciamo in modo che il nostro Web User Control venga memorizzato nella cache
per un tempo di 100 secondi. Se anche la pagina aspx che contiene lo User Control ha una direttiva per un tempo inferiore:
<% @OutputCache duration="50" varybyparam="none" %>
il nostro Web User Control verrà ricaricato in base alla sua direttiva
e quindi ogni 100 secondi e non secondo la direttiva della pagina che lo ospita.
Vi invito ad approfondire, nella documentazione che potete trovare su MSDN, la
possibilità di usare il fragment caching per i nostri Web User Control.