3 pagine in totale: <<Indietro 1 [2] 3 Avanti >>
Naturalmente la funzione che vogliamo referenziare non deve essere obbligatoriamente presente nella stessa classe principale. Se essa fosse presente in una terza classe da istanziare per poterla utilizzare, dovremo scrivere:
[C#]:
namespace Esempio
{
public delegate string Funzione(string nome);
public class Classe2
{
public Funzione xfunzione;
public void InviaSaluto()
{
HttpContext.Current.Response.Write(xfunzione("Andrea"));
}
}
Public class Classe3
{
public string Saluto(string nome)
{
return "Ciao "+nome;
}
}
public class Delegate : System.Web.UI.Page
{
private void Page_Load(object sender, System.EventArgs e)
{
Classe3 classe3=new Classe3();
Classe2 classe=new Classe2();
classe.xfunzione=new Funzione(classe3.Saluto);
classe.InviaSaluto();
}
}
}
[VB]:
Public Delegate Function Funzione(ByVal nome As String) As String
Public Class Class3
Public Function Saluto(ByVal nome As String) As String
Return "Ciao " + nome
End Function
End Class
Public Class Classe2
Public xfunzione As Funzione
Sub ScriviSaluto()
HttpContext.Current.Response.Write(xfunzione("Andrea"))
End Sub
End Class
Public Class Delegate
Inherits System.Web.UI.Page
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs)
Dim class3 As New Classe3
Dim classe As New Classe2
classe.xfunzione = New Funzione(AddressOf class3.Saluto)
classe.ScriviSaluto()
End Sub
End ClassUn uso pratico dei delegate
A questo punto il lettore si starà chiedendo quale sia l'utilità pratica del delegate e se ora più che mai si sta convincendo che non lo siano, dovrà ricredersi quando riscontrerà la sua effettiva utilità nello scambio di informazioni tra user-control o classi strutturate su più strati dell'applicazione. Se volessimo, per fare un esempio, poter richiamare o utilizzare una funzione, un web control, o un qualsiasi altro oggetto presente nella pagina in un nostro user-control caricato dinamicamente all'interno della pagina, come dovremmo comportarci?
Chi programma ormai da tempo e si è fatto le ossa direttamente sul campo, saprà che per il problema dei controlli al di fuori dell'user control è facilmente risolvibile utilizzando il metodo FindControl , da usare per trovare il Control interessato. Una piccola annotazione per questa tecnica è d'obbligo: anche se questa soluzione funziona perfettamente, è consigliabile non utilizzare il FindControl date le sue basse prestazioni, poichè, in fase di runtime, il Framework deve effettuare una ricerca all'interno dei controlli. La soluzione migliore è l'accesso diretto a questo oggetto, possibile solo sfruttando i delegate.
Vediamo due esempi di uno user control che accede direttamente ad una funzione presente all'interno della pagina principale che la contiene. Nel primo cao vi accederemo collegandoci alla funzione in questione e richiamando la classe della pagina stessa (gli esempi d'ora in poi saranno realizzati solo in C#):
// Pagina_Principale.aspx
<%@ Register TagPrefix="uc1" TagName="UserControl1" src="UserControl1.ascx" %>
//?
public class WebForm1 : System.Web.UI.Page
{
protected System.Web.UI.WebControls.Label Label1;
protected UserControl1 uc;
public void SetText(string testo)
{
Label1.Text=testo;
}
}
All'interno di questa pagina è presente solo un control Label ed uno user control. Lo user-control è composto solo da un button che avvierà l'evento, per richiamare la funzione "SetText" presente nella pagina principale a cui sarà passato la data e l'ora odierna:
// UserControl1.ascx
public class UserControl1 : System.Web.UI.UserControl
{
protected System.Web.UI.WebControls.Button Button1;
private void Button1_Click(object sender, System.EventArgs e)
{
WebForm1 wb=(WebForm1)this.Page;
wb.SetText(DateTime.Now.ToString());
return;
}
}E' senza dubbio una tecnica semplice e molto funzionale, ma presenta dei problemi di flessibilità non indifferenti. Se volessimo inserire questo user control all'interno di altre pagine, non potremo più utilizzare l'evento visto che si referenzierà con la classe "WebForm1" presente solo in una pagina. Ed in ultimo, anche se il calo di prestazioni è minimo, tale tecnica abbisogna sempre di una conversione esplicita (
WebForm1 wb=(WebForm1)this.PageVediamo ora del codice che fa le stesse operazioni ma con l'uso dei delegate:
// Pagina_principale.aspx
<%@ Register TagPrefix="uc1" TagName="UserControl1" src="UserControl1.ascx" %>
//?
public class WebForm1 : System.Web.UI.Page
{
protected System.Web.UI.WebControls.Label Label1;
protected UserControl1 uc;
public void SetText(string testo)
{
Label1.Text=testo;
}
private void Page_Load(object sender, System.EventArgs e)
{
uc.AZHandler+=new AZHandler1(this.SetText);
}
}C'è una sola modifica rispetto al codice prima esposto: l'aggiunta dell'evento Page_Load, che spiegheremo di seguito. Vediamo ora il codice dello user control:
public delegate void AZHandler1(string testo);
public class UserControl1 : System.Web.UI.UserControl
{
protected System.Web.UI.WebControls.Button Button1;
public AZHandler1 AZHandler;
private void Button1_Click(object sender, System.EventArgs e)
{
// Controllo che sia stata assegnata una funzione?
if (AZHandler!=null)
AZHandler(DateTime.Now.ToString());
}
}Anche qui sono presenti alcune linee di codice aggiuntive, ed anche questo codice esegue l'evento richiamando la funzione "SetText", ma a differenza del primo esempio, l'evento sarà richiamato senza alcun tipo di conversione e senza la limitazione di sapere il nome della classe della pagina?
3 pagine in totale: <<Indietro 1 [2] 3 Avanti >>
Attenzione: Questo articolo contiene un allegato
Contenuti dell'articolo
Aggiungi un nuovo commento »»»
Per inserire un commento, devi registrarti alla nostra community.







Difficoltà

Stampa
Download



