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="€ {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.
Commenti
Per inserire un commento, devi avere un account.
Fai il login e torna a questa pagina, oppure registrati alla nostra community.