Creare colonne personalizzate di un DataGrid

di Cristian Civera, in ASP.NET,
  • 0
  • 0
  • 0
  • 1,86 KB

Chi utilizza il DataGrid avrà senz'altro usato oggetti come BoundColumn, TemplateColumn, ButtonColumn ed altri che vanno a popolare la collezione Columns del datagrid.

Tutte queste classi hanno in comune la particolarità che ereditano da una classe di base, DataGridColumn : nulla ci vieta quindi di ereditare da questa classe e creare una nostra colonna per dare più funzionalità al nostro datagrid.

Perché questa scelta?

Rispetto all'uso degli eventi ItemDataBound o ItemCreated non offre potenzialità maggiori, ma in compenso rende il nostro codice ordinato, elegante e riutilizzabile in più occasioni: potremo infatti riutilizzare questa colonna personalizzata nell'ambito di tutti i datagrid, senza aggiungere codice particolare.

Un esempio: MathColumn

Prendiamo come esempio la creazione di un MathColumn, una colonna in grado di eseguire delle operazioni matematiche prendendo come valori erti campi della nostra sorgente dati.

In particolare aggiungeremo una proprietà DataFields , per indicare, separati da una virgola, i campi della nostra sorgente da utilizzare, una proprietà DataFormatString per formattare il risultato (proprietà del tutto simile a quella esposta dalla classe BoundColumn) e un'ultima proprietà Operation di tipo MathOperation (variabile enum creata da noi) per scegliere fra le quattro operazioni (Sum, Avg, Min, Max)

Come procedete? Per prima cosa dobbiamo creare una classe nuova che erediti da DataGridColumn del namespace System.Web.UI.WebControls:

namespace ASPItalia.com
{
  public class MathColumn:System.Web.UI.WebControls.DataGridColumn
  {
   public MathColumn():base()
   {
   }
  }
}

A questo punto dobbiamo creare le proprietà pubbliche che ci servono:

namespace ASPItalia.com
{
  public class MathColumn:System.Web.UI.WebControls.DataGridColumn
  {
   public MathColumn():base()
   {
   }
   private int columnIndex=0;
   private MathOperation operation=MathOperation.Sum;
   private string dataFields="";
   private string dataFormatString="{0}";
   private string[] fields=new string[0];
   public MathOperation Operation
   {
     get
     {
       return operation;
     }
     set
     {
       operation=value;
     }
   }
   public string DataFormatString
   {
     get
     {
       return dataFormatString;
     }
     set
     {
       dataFormatString=value;
     }
   }
   public string DataFields
   {
     get
     {
       return dataFields;
     }
     set
     {
       dataFields=value;
       //preleva la lista dei campi
       fields=dataFields.Split(new Char[]{Convert.ToChar(",")});
     }
   }

Ora non ci resta che definire anche il nostro tipo enum MathOperation:

  public enum MathOperation
  {
   Sum,
   Avg,
   Min,
   Max
  }

A questo punto nella nostra classe MathColumn dobbiamo sovrascrivere il metodo InitializeCell che viene richiamato ogni volta viene creata la nuova cella della rispettiva riga-colonna e memorizzare in quale indice di colonna si trova il nostro MathColumn.

   public override void InitializeCell(TableCell cell,int columnIndex,ListItemType itemType)
   {
     //chiama il metodo base
     base.InitializeCell(cell,columnIndex,itemType);
     this.columnIndex=columnIndex;
   }

Il metodo base scrive già da solo nell'header il nome della colonna, dunque non c'è bisogno di sovrascrivere nulla.

Invece dobbiamo sovrascrivere il metodo Initialize , che viene richiamato quando la colonna viene creata e ne vengono valorizzate le proprietà, sfruttando la variabile Owner per gestire l'evento ItemDataBound:

   public override void Initialize()
   {
     base.Initialize();
     Owner.ItemDataBound+=new DataGridItemEventHandler(onDataBound);
   }

In questo modo per ogni riga creata, verrà richiamata la nostra funzione onDataBound, in modo da poter eseguire le nostre operazioni matematiche e valorizzare la nostra cella con il risultato.

   private void onDataBound(object s, DataGridItemEventArgs e)
   {
     if (e.Item.DataItem!=null)
     {
       //riferimento al valore
       DataRowView r=e.Item.DataItem as DataRowView;
       if (r==null) return;
       //risultato
       float math=(operation==MathOperation.Min)?float.MaxValue:0f;
       foreach (string field in fields)
       {
        float v=Convert.ToSingle(r[field]);
        if ((operation==MathOperation.Min && v<math) ||
          (operation==MathOperation.Max && v>math))
          math=v;
        else if (operation==MathOperation.Sum || operation==MathOperation.Avg)
          math+=v;
       }
       if (operation==MathOperation.Avg)
        math/=fields.Length;
       e.Item.Cells[columnIndex].Text=string.Format(DataFormatString,math);
     }
   }

La proprietà Item del paramentro e di tipo DataGridItemEventArgs restituisce la riga corrente. Da questa possiamo ricavare la sorgente relativa alla riga corrente, eseguire le nostre operazioni matematiche e valorizzare la cella corretta mediante la variabile privata (che avevamo precedentemente memorizzato) columnIndex.

Utilizzare la classe

Non ci resta che compilare l'assembly. Per utilizzarlo nelle nostre pagina ASP.NET dobbiamo registrare il nostro controllo attraverso la direttiva @Register:

<%@ Register tagPrefix="ASPItalia" namespace="ASPItalia.com" assembly="MathColumn" %>

Ora nella nostra pagina possiamo aggiungere la nostra colonna MathColumn tra le altre:

<asp:DataGrid>
  <Columns>
   <asp:BoundColumn.. >
   <ASPItalia:MathColumn DataFields="Prezzo1,Prezzo2" Operation="AVG" HeaderText="Media" DataFormatString="&euro; {0:#,##0.00}"/>
  </Columns>
</asp:DataGrid>

La proprietà HeaderText è già contenuta in DataGridColumn e potremo sfruttarla per dare un nome alla nostra colonna.

Se non riuscite a mettere insieme il codice presentato nell'articolo, nell'allegato c'è il codice sorgente completo insieme ad un esempio per l'uso.

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