Nell’utilizzo del controllo DataGridView per la visualizzazione e inserimento dati, vi sono occasioni in cui esiste la necessità di estendere le primitive relative alle celle, dotando la propria griglia di funzionalità avanzate rispetto a quelle basilari. Proprio a partire dai tipi originari del controllo, è possibile sviluppare nuove tipologie di colonne e celle, attraverso le quali gestire in modo più puntuale i vari scenari con i quali potremmo avere a che fare.

A titolo di esempio, in questo articolo mostrerò come creare una tipologia di colonna (e relativa cella) che gestisca unicamente valori numerici, ed eventuali situazioni di violazione di tale vincolo. Iniziamo con l’osservare un esempio di classe relativo alla cella:

public class emDGVNumericCell: DataGridViewTextBoxCell {

        public emDGVNumericCell(){

            DataGridViewCellStyle cellStyle = new DataGridViewCellStyle();

            cellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;

            cellStyle.NullValue = "0";

            cellStyle.WrapMode = DataGridViewTriState.False;

            this.Style = new DataGridViewCellStyle(cellStyle);

        }

        protected override void OnLeave(int rowIndex, bool throughMouseClick){

            base.OnLeave(rowIndex, throughMouseClick);

            rowIndex, bool throughMouseClick)Decimal tmp = 0;

            if (!Decimal.TryParse(this.Value.ToString(), out tmp))

            {

                MessageBox.Show("Formato Dati non valido. Inserire un valore numerico.");

                this.Value = 0;

            }

        }

}

In modo molto semplice, ho dichiarato una nuova classe, emDGVNumericCell, estensione del tipo ad essa logicamente più affine, ovvero DataGridViewTextBoxCell. Nel suo costruttore, viene definito uno stile che prevede un allineamento del testo a destra, ed un valore di default in caso di null pari a zero. Dunque, alla creazione della nostra cella, essa avrà per impostazione predefinita lo stile appena creato.

Il controllo sulla correttezza del valore digitato viene effettuato, in questo caso, durante la fase di uscita dalla cella, ovvero eseguendo l’override dell’evento OnLeave(). Al suo interno, dichiariamo una variabile temporanea di tipo  Decimal, e tentiamo una conversione del testo inserito nella cella. Se esso risulta essere numerico (ovvero, se la conversione va a buon fine), lasceremo proseguire l’elaborazione, mentre in caso contrario emetteremo una  che informa della violazione, impostando a zero il valore del controllo.

Per poter utilizzare la nostra cella, avremo necessità di creare un tipo di colonna il cui template sia appunto la classe appena creata. Molto banalmente, potremo quindi scrivere la seguente classe:

public class emDGVNumericColumn: DataGridViewTextBoxColumn{

   public emDGVNumericColumn() {

     this.CellTemplate = new emDGVNumericCell();

   }

}

Il costruttore della nostra classe prevederà, in questo caso, unicamente la definizione della proprietà CellTemplate, in modo da legare la nuova colonna al nuovo tipo di cella. Compilando le nostre classi, la nuova colonna diverrà disponibile tra i valori possibili per la proprietà ColumnType, in fase di definizione della proprietà Columns della nostra DataGridView:



In fase di runtime, il suo comportamento seguirà logicamente quanto da noi implementato:

    

Naturalmente si tratta di un esempio banale, che però apre la strada a implementazioni decisamente più complesse, applicando gli stessi principi visti fin qui, e andando a creare gli elementi di cui si necessita per ciascun caso specifico.