asp - asp.net - aspcode.it

COMMUNITY - Login
 Username:
 
 Password:
 
Voglio registrarmi!
Password dimenticata?
 Utenti on-line: 0
 Ospiti on-line: 3324
ASPCode.it - Store

  > > Articoli

Un esempio di EventHandling: intercettare celle nulle di DataGrid

Data di pubblicazione: 29/10/2003        Voto della community: 4,50 (Votanti: 2)

Il precedente articolo, La gestione degli eventi in ASP.NET, illustrava la gestione degli eventi in ASP.NET con particolare riferimento agli eventi intrinseci della classe Page. In quel caso, come è detto, il codice relativo alla fase di pubblicazione (la fase logicamente precedente quella di sottoscrizione) dell'evento è nascosto allo sviluppatore trovandosi già nella definizione della classe Page del framework; questi puo' quindi sottoscrivere gli eventi intrinseci della classe Page per "attaccare" proprio codice.
In questo articolo vediamo invece un esempio pratico di pubblicazione di un evento da noi definito e di successiva sottoscrizione.

Vogliamo intercettare le eventuali celle nulle di un DataGrid e agire di conseguenza. Per fare cio', lanceremo un nostro evento personale ogniqualvolta, durante il databinding dei dati alle rispettive celle del DataGrid, verrà intercettata una cella associata ad un campo nullo nella sorgente dati. A tale evento assoceremo quindi un nostro event handler, che reagirà all'evento.

La sorgente dati è la tabella Ordini del database Northwind formato Access (che presenta di default vari record con campi nulli).

<%@ Page Language="C#" Debug="true" Trace="false" %>
<%@ import Namespace="System.Data" %>
<%@ import Namespace="System.Data.OleDb" %>
<script runat="server">

    public delegate void mioEventHandler (object sender, mioEventArgs e);
   
    public class mioEventArgs : EventArgs {
   
        public readonly string ValoreChiave;
        public readonly int NColonna;
   
        public mioEventArgs(string ValoreChiave, int NColonna)  {
            this.NColonna = NColonna;
            this.ValoreChiave = ValoreChiave;
        }
    }
   
    public event mioEventHandler CellaNulla;
   
    void On_CellaNulla (mioEventArgs e){
            CellaNulla (this, e);
    }

   
   
    void GestioneEvento (Object sender, mioEventArgs e) {
              Response.Write (e.ValoreChiave + "--->colonna nulla:" + (e.NColonna+1) + "<font size=-1>a</font><br>");
    }
   
   
    void Page_Init () {
          CellaNulla += new mioEventHandler (GestioneEvento);
    }
   
    void _itemDataBound (Object o, DataGridItemEventArgs e ) {
   
      if((e.Item.ItemType == ListItemType.Item) || (e.Item.ItemType == ListItemType.AlternatingItem)) {
   
            DataRowView drv = (DataRowView)e.Item.DataItem;
   
            for (int i=0; i<drv.Row.ItemArray.Length; i++) {
   
                if ( (drv.Row.ItemArray[i]) ==System.DBNull.Value ) {
                      On_CellaNulla (new mioEventArgs(e.Item.Cells[0].Text, i));
                }
            }
      }
    }
   
   
    void  Page_Load( Object Source, EventArgs E) {
   
      string strCnn = "Provider=Microsoft.Jet.OLEDB.4.0; Data Source=D:/ASPCODE/Northwind.mdb";
   
      OleDbConnection cnn = new OleDbConnection(strCnn) ;
   
      DataSet ds = new DataSet();
      OleDbDataAdapter da0 = new OleDbDataAdapter();
   
      OleDbCommand cmd0 = new OleDbCommand("SELECT TOP 20 * FROM Ordini ORDER BY [IDOrdine] DESC", cnn);
      da0.SelectCommand = cmd0;
   
      cnn.Open();
      da0.Fill(ds, "miaTabella");
   
      DataTable dt = ds.Tables["miaTabella"];
      DataView dv = new DataView(dt);
      cnn.Close();
   
   
      DataGrid1.DataSource = dv;
      DataGrid1.DataBind();
  }

</script>

<html>
<head>
</head>
<body>
    <form runat="server">
        <p>
            <asp:DataGrid id="DataGrid1" runat="server" OnItemDataBound="_itemDataBound"></asp:DataGrid>
        </p>
        <p>
        </p>
    </form>
</body>
</html>

La parte di codice in grassetto è quella designata alla pubblicazione dell'evento (la sottoscrizione consiste nelle procedure GestioneEvento e nell'istruzione che troviamo in Page_Init). Per prima cosa notiamo la definizione dell'evento CellaNulla; il delegato all'evento, come si vede in tale definizione, è mioEventHandler. Più sopra, troviamo l'istruzione public delegate..., che definisce la signature del delegato mioEventHandler, ovvero a che tipo di procedura farà riferimento mioEventHandler. Come si vede, mioEventHandler farà riferimento ad una procedura che non restituisce valori (void) e che riceve due parametri, uno di tipo Object, l'altro di tipo mioEventArgs. mioEventArgs è la classe che si occupa di "conservare" le informazioni circa l'evento; deriva da EventArgs, che è la classe base per quegli eventi che non passano informazioni circa l'evento stesso. Nel nostro caso, mioEventArgs si occupa di conservare due parametri e di esporli come proprietà (i due valori che passeremo saranno il numero della colonna nulla intercettata e il valore della colonna 0  - che è normalmente unico/chiave primaria - di quel record).
Quando la procedura _ItemDataBound intercetta una cella associata ad un campo nullo nella sorgente dati, viene chiamata la procedura On_CellaNulla passandole una istanza della classe mioEventArgs con i due parametri sopra anticipati. On_CellaNulla è la procedura che si occupa finalmente di lanciare l'evento, caratterizzato da una istanza della classe Page (il this) per informare i sottoscrittori circa l'oggetto che ha generato l'evento, e l'istanza di mioEventArgs ricevuta da _ItemDataBound.

Per sottoscrivere l'evento pubblicato, abbiamo definito la nostra procedura event handler GestioneEvento con la stessa signature del delegato. Nella fase Page_Init creiamo una istanza del delegato mioEventHanlder come - appunto - delegato della nostra procedura GestioneEvento e colleghiamo tale istanza al nostro evento CellaNulla.

Per completezza, facciamo seguire la versione di tale codice nel caso in cui non vengano passate informazioni circa l'evento (i numero della colonna vuota e il valore della colonna0 dello stesso record). L'output sarà semplicemente una serie di messaggi di notifica dell'evento.

<%@ Page Language="C#" Debug="true" Trace="false" %>
<%@ import Namespace="System.Data" %>
<%@ import Namespace="System.Data.OleDb" %>
<script runat="server">

    public event EventHandler CellaNulla;
   
    void On_CellaNulla (EventArgs e){

      CellaNulla (this, e);
    }
   
   
    void GestioneEvento (Object sender, EventArgs e) {
   
        Response.Write ("Trovata cella nulla<br>");
    }
   
   
    void _itemDataBound (Object o, DataGridItemEventArgs e ) {

            if((e.Item.ItemType == ListItemType.Item) || (e.Item.ItemType == ListItemType.AlternatingItem)) {
   
                    DataRowView drv = (DataRowView)e.Item.DataItem;
   
                    for (int i=0; i<drv.Row.ItemArray.Length; i++) {
   
                        if (  (drv.Row.ItemArray[i]) ==System.DBNull.Value ) {
   
                            On_CellaNulla ( new EventArgs() );
                        }
                    }
            }
    }
   
   
   
    void Page_Init () {

    CellaNulla += new EventHandler (GestioneEvento);

    }

    void  Page_Load( Object Source, EventArgs E)    {
 
    string strCnn = "Provider=Microsoft.Jet.OLEDB.4.0; Data Source=D:/ASPCODE/Northwind.mdb";
   
    OleDbConnection cnn = new OleDbConnection(strCnn) ;

    DataSet ds = new DataSet();
    OleDbDataAdapter da0 = new OleDbDataAdapter();
   
    OleDbCommand cmd0 = new OleDbCommand("SELECT TOP 20 * FROM Ordini ORDER BY [IDOrdine] DESC", cnn);
    da0.SelectCommand = cmd0;
   
    cnn.Open();
    da0.Fill(ds, "miaTabella");
   
    DataTable dt = ds.Tables["miaTabella"];
    DataView dv = new DataView(dt);
    cnn.Close();
   
   
    DataGrid1.DataSource = dv;
    DataGrid1.DataBind();
     
    }

</script>

<html>
<head>
</head>
<body>
    <form runat="server">
        <p>
        </p>
        <p>
        </p>
        <p>
            <asp:DataGrid id="DataGrid1" runat="server" OnItemDataBound="_itemDataBound"></asp:DataGrid>
        </p>
        <p>
        </p>
    </form>
</body>
</html>

Come si nota, manca la dichiarazione della classe mioEventArgs e del delegato mioEventHandler; ci serviamo infatti della classe predefinita EventArgs  e del delegato EventHandler che ha la signature predefinita del tipo:

public delegate void EventHandler (object sender, EventArgs e)

Resta da chiedersi quali vantaggi derivino dall'avere utilizzato la tecnica di generare un evento in corrispondenza di una cella vuota rispetto alla soluzione più semplice di richiamare direttamente  una procedura al verificarsi di tale condizione. Ci basta pensare che, in risposta allo stesso evento è possibile attaccare più procedure con compiti diversi, oltre alla possibilità di riutilizzare una stessa procedura di event handling attaccandovi eventi diversi purché l'evento sia dello stesso tipo (stessa signature nel delegato all'evento)




Utenti connessi: 3324