Tecniche di scambio dati tra user control

di Cristiano Degiorgis, in ASP.NET,

Sviluppando un'applicazione complessa basata su user control annidati, mi si è presentata l'esigenza di scambiare dati tra più user control. Fino a che il padre deve passare dati al figlio il problema non si pone. Più complesso è lo scenario opposto: il figlio che deve passare dati al controllo padre.

La mia applicazione, dato che ASP.NET 2.0 e le sue master page erano ancora lontano al momento in cui ho iniziato a sviluppare, si compone di una unica pagina che carica al suo interno dinamicamente degli user control. Questi user control a loro volta includono altri user control usati più volte in relazione agli scenari dell'applicazione. Per semplicità andrò ad esporre il passagio di dati tra uno user control e la pagina che lo ospita, ma sappiate che funziona ugualmente nello scenario che vi ho appena esposto.

Lo scenario

Supponiamo di avere una pagina contente un form e tra i cui campi via sia una combo per selezionare un cliente. Supponiamo che nella nostra applicazione si presenti più volte l'esigenza di avere una combo con l'elenco dei clienti e non abbiamo voglia di crearne una per pagina con il relativo codice necessario per il popolamento e per l'intercettazione della scelta. Decidiamo quindi di sviluppare uno user control che contenga tutte le funzionalità per gestire questa combo.

L'obiettivo

Una volta creato lo user control dovremmo fare in modo di intercettare dalla pagina che lo contiene il valore selezionato. Se l'obiettivo fosse solo questo, la classe System.Web.UI.Control ci mette a disposione il metodo FindControl che ci restituisce l'oggeto che ci interessa all'interno dello user control. Vogliamo, oltre recuperare il valore selezionato nello user control, anche fare in modo che a fronte di questa selezione la pagina compia una determinata operazione.

La soluzione più elegante per ottenere tutto questo è fare in modo che, a fronte di un'operazione compiuta attraverso lo user control (nel nostro caso la scelta di un cliente), venga chiamato un metodo presente nella nostra pagina.

Per ottenere questo risultato ho trovato tre possibili strade:

  • Interfacce
  • Delegati
  • Eventi

Non starò ad illustrare caratteristiche e peculiarità di questi tre "strumenti" in quanto ciascuno meriterebbe un articolo a sè. Tra gli approfondimenti troverete una buona documentazione per chiarirvi eventuali dubbi o lacune in merito.

Utilizzo delle Interfacce

Scegliendo la soluzione basata sulle interfacce occorre seguire alcuni passagi.

Per prima cosa bisogna creare un'apposita interfaccia:

 public interface IRiceviCliente { 
  void Ottieni_Cliente_Cambiato_1( int codCliente, string descCliente ); 
} 

Poi far ereditare la pagina dall'interfaccia creata:

 public class EsInterface : System.Web.UI.Page, IRiceviCliente <b>...</b> 

Ancora, scrivere nella pagina un metodo richiesto dall'interfaccia:

 public void Ottieni_Cliente_Cambiato_1( int codCliente, string descCliente ) {
  ViewState["CodCliente"] = codCliente;
  ViewState["DescCliente"] = descCliente;
}

Richiamare questo metodo sull'evento OnSelectedIndexChanged della combo presente nello user control:

 // Step4: Richiamare questo metodo sull'evento OnSelectedIndexChanged della 
// combo presente nello user control
protected void Cambio_Cliente(object sender, System.EventArgs e){
  ((IRiceviCliente) this.NamingContainer).Ottieni_Cliente_Cambiato_1(    Int32.Parse(ddlClienti.SelectedItem.Value),
   ddlClienti.SelectedItem.Text );
}

Grazie all'implementazione dell'Interfaccia

IRiceviCliente
la nostra pagina espone il metodo che andiamo a richiamare dallo user control. Dato che lo user control si trova direttamente nella pagina so che
 this.NamingContainer
è la nostra pagina e ne posso fare il cast in quanto so che questa implementa l'interfaccia.

Utilizzo dei delegate

Durante lo sviluppo della mia applicazione mi è capitato di leggere un articolo che trattava dello stesso problema che stiamo affrontando e lo risolveva utilizzando i delegate. La soluzione che andrò ad esporvi ora si basa esattamente su questo articolo.

Scegliendo la soluzione basata sui delegate occorre definire un delegate nella pagina:

 delegate void DelClienteCambiato( int codCliente, string descCliente );

Quindi aggiungere allo user control una proprietà di tipo delegate:

 private System.Delegate _DelClienteCambiato;
public System.Delegate DelClienteCambiato {
  set{ _DelClienteCambiato = value;}
} 

Creare un'istanza nella pagina(ad esempio nel Page_Load) del delegato definito alla step 1 e passare questa istanza allo user control attraverso la proprietà creata allo step 2:

 private void Page_Load(object sender, System.EventArgs e){
  DelClienteCambiato delClienteCambiato = 
   new DelClienteCambiato(this.Ottieni_Cliente_Cambiato_2);
  this.ClientiDelegate1.DelClienteCambiato = delClienteCambiato;
}

Da noteare che occorre creare l'istanza del delegato e passarla allo user control ad ogni post della pagina.

Dobbiamo poi scrivere nella pagina un metodo coerente con il delegato definito allo step 1:

 private void Ottieni_Cliente_Cambiato_2( int codCliente, string descCliente ) {
  ViewState["CodCliente"] = codCliente;
  ViewState["DescCliente"] = descCliente;
}

Invocare il delegato sull'evento OnSelectedIndexChanged della combo presente nello user control:

 protected void Cambio_Cliente(object sender, System.EventArgs e){
  if(_DelClienteCambiato != null){
   Object[] aObj = new Object[2];
   aObj[0] = Int32.Parse(ddlClienti.SelectedItem.Value);
   aObj[1] = ddlClienti.SelectedItem.Text;

  _DelClienteCambiato.DynamicInvoke(aObj);
}
2 pagine in totale: 1 2

Attenzione: Questo articolo contiene un allegato.

Contenuti dell'articolo

Commenti

Visualizza/aggiungi commenti

| Condividi su: Twitter, Facebook, LinkedIn

Per inserire un commento, devi avere un account.

Fai il login e torna a questa pagina, oppure registrati alla nostra community.

Approfondimenti