Pagina personale di:
Carlo Vecchio
appunti di C#, R, SQL Server, ASP.NET, algoritmi, numeri
Vai ai contenuti

C# - Lavorare con le data grid view

C#

Alcune proprietà importanti

  • Esempio di utilizzo di alcune proprietà:

   dgv1.AllowDrop = false;
   dgv1.AllowUserToAddRows = false;
   dgv1.AllowUserToDeleteRows = false;
   dgv1.EditMode = DataGridViewEditMode.EditProgrammatically;
   dgv1.MultiSelect = false;
   dgv1.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.DisableResizing;
   dgv1.ColumnHeadersHeight = 25;
   dgv1.RowHeadersWidth = 25;

Cella corrente, prima riga e prima colonna
  • Memorizzare le coordinate della cella corrente, della prima riga e della prima colonna.

   int RowIndex = dgv1.CurrentCell.RowIndex;
   int ColIndex = dgv1.CurrentCell.ColumnIndex;
   int FirstDisplayedRowIndex = dgv1.FirstDisplayedScrollingRowIndex;
   int FirstDisplayedColIndex = dgv1.FirstDisplayedScrollingColumnIndex;

  • Impostare la cella corrente, la prima riga e la prima colonna.

   dgv1.CurrentCell = dgv1.Rows[RowIndex].Cells[ColIndex];
   dgv1.FirstDisplayedScrollingRowIndex = FirstDisplayedRowIndex;
   dgv1.FirstDisplayedScrollingColumnIndex = FirstDisplayedColIndex;

Impostare stili
  • Esempio di utilizzo di uno stile di una cella.

   DataGridViewCellStyle gridStyle = new DataGridViewCellStyle();
   gridStyle.BackColor = SystemColors.ControlLightLight;
   gridStyle.ForeColor = Color.Black;
   gridStyle.SelectionBackColor = Color.SandyBrown;
   gridStyle.Font = new Font("Verdana", 8);
   dgv1.DefaultCellStyle = gridStyle;

  • Esempio di utilizzo di uno stile di una colonna.

   DataGridViewCellStyle colStyle = new DataGridViewCellStyle();
   colStyle.BackColor = SystemColors.Control;
   colStyle.ForeColor = Color.Black;
   colStyle.Font = new Font("Verdana", 8, FontStyle.Bold);
   colStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;
   dgv1.ColumnHeadersDefaultCellStyle = colStyle;

Aggiungere colonne runtime
  • Esempio di come aggiungere una colonna tramite codice.
  • Altre colonne si possono aggiungere in modo analogo modificando solo la prima riga (togliere il tipo 'DataGridViewTextBoxColumn').

   DataGridViewTextBoxColumn colTmp = new DataGridViewTextBoxColumn();
   colTmp.Tag = COL_CODICE;
   colTmp.HeaderText = "Codice";
   colTmp.Name = "colCodice";
   colTmp.DataPropertyName = "Codice"; // Impostare uguale alla proprietà dell'oggetto
   colTmp.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
   colTmp.Width = 100;
   dgv1.Columns.Add(colTmp);

Caricare dati da una lista di oggetti
  • Ci sono vari modi per caricare dati in una DataGridView. Un metodo è quello di mettere una lista di oggetti in binding con la DataGridView.
  • La prima cosa da fare è definire una classe i cui oggetti rappresentano le righe da visualizzare nella griglia.
  • In questo esempio si definisce la classe 'Persone' in questo modo:

   public class Persone
   {
       public string Nome { get; set; }
       public string Cognome { get; set; }
       public DateTime DataDiNascita { get; set; }

       public Persone(string nome, string cognome, DateTime dataDiNascita)
       {
           Nome = nome;
           Cognome = cognome;
           DataDiNascita = dataDiNascita;
       }
   }

  • La classe ha tre proprietà ('Nome', 'Cognome' e 'DataDiNascita'): queste proprietà saranno messe in 'binding' con le colonne della griglia.
  • È presente anche un costruttore, utile per generare velocemente gli oggetti (si veda il codice successivo).
  • Il secondo passo da fare è definire una lista di oggetti, in questo esempio di oggetti di tipo 'Persone'.
  • Questa definizione deve essere inserita all'interno della classe 'Form', perché l'oggetto 'lstData' deve essere visibile da tutti i metodi della Form.

   // Lista con gli oggetti da mostrare in griglia
   BindingList<Persone> lstData = new BindingList<Persone>();

  • Il terzo passo è quello di inserire un paio di controlli nella Form: un Button (in questo esempio è 'button1') e una DataGridView (chiamata 'dgvData').
  • Infine nell'evento click del Button occorre inserire il codice seguente:

   private void button1_Click(object sender, EventArgs e)
   {
       // Imposta colonne della griglia.
       dgvData.Columns.Clear();
 
       DataGridViewTextBoxColumn col1 = new DataGridViewTextBoxColumn();
       col1.DataPropertyName = "Nome";
       col1.HeaderText = "Nome";
       col1.Name = "colNome";
       col1.ValueType = typeof(string);
       col1.Width = 100;
       col1.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleLeft;
       col1.ReadOnly = true;
       col1.MinimumWidth = 50;
       dgvData.Columns.Add(col1);
 
       DataGridViewTextBoxColumn col2 = new DataGridViewTextBoxColumn();
       col2.DataPropertyName = "Cognome";
       col2.HeaderText = "Cognome";
       col2.Name = "colCognome";
       col2.ValueType = typeof(string);
       col2.Width = 100;
       col2.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleLeft;
       col2.ReadOnly = true;
       col2.MinimumWidth = 50;
       dgvData.Columns.Add(col2);

       DataGridViewTextBoxColumn col3 = new DataGridViewTextBoxColumn();
       col3.DataPropertyName = "DataDiNascita";
       col3.HeaderText = "Data di nascita";
       col3.Name = "colDataDiNascita";
       col3.ValueType = typeof(DateTime);
       col3.Width = 100;
       col3.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
       col3.ReadOnly = true;
       col3.MinimumWidth = 50;
       dgvData.Columns.Add(col3);

       // Carica i dati nella lista
       lstData.Clear();
       lstData.Add(new Persone("Isaac", "Asimov", new DateTime(1920, 1, 2)));
       lstData.Add(new Persone("Ray", "Bradbury", new DateTime(1920, 8, 22)));
       lstData.Add(new Persone("Philip K.", "Dick", new DateTime(1928, 12, 16)));
       lstData.Add(new Persone("Arthur C.", "Clarke", new DateTime(1917, 12, 16)));
       lstData.Add(new Persone("William", "Gibson", new DateTime(1948, 3, 17)));

       // La dgv si aggiorna da sola perché la lista è BindingList
       dgvData.DataSource = lstData;   
   }

  • Il primo blocco di righe definisce le colonne della griglia, segue il caricamento della lista 'lstData' e infine il binding della lista con la griglia.
  • È importante impostare nelle colonne della griglia la proprietà 'DataPropertyName' uguale alla proprietà della classe 'Persone'.
  • Il risultato è il seguente:



Celle selezionate
  • Se la DataGridView permette la selezione multipla di celle, il codice seguente permette di identificare le celle selezionate.
  • Si abbia una DataGridView con 3 colonne e 5 righe; quattro celle siano selezionate.


  • Per aggiungere le righe e le colonne, il codice è il seguente:

   private void Form1_Load(object sender, EventArgs e)
   {
       dgv1.ColumnCount = 3;
       dgv1.RowCount = 5;
   }


  • Per identificare le celle selezionate è sufficiente utilizzare il metodo 'SelectedCells'.


   private void button1_Click(object sender, EventArgs e)
   {
       var allCells = dgv1.SelectedCells;
       foreach (DataGridViewCell c in allCells)
       {
           Console.WriteLine("Riga: " + c.RowIndex + " Colonna: " + c.ColumnIndex);
       }

   }


  • Al click del bottone, nella finestra 'Output' di Visual Studio si ottiene:

  Riga: 1 Colonna: 1
  Riga: 0 Colonna: 1
  Riga: 1 Colonna: 0
  Riga: 0 Colonna: 0


  • Ricordare che gli indici di riga e di colonna ('RowIndex' e 'ColIndex') sono a base 0, cioè partono da 0.

Testo multilinea nelle celle
  • Nelle celle di una DataGridView può essere inserito del testo su più linee.
  • Basta impostare la proprietà 'DefaultCellStyle' della colonna. Per esempio con il codice seguente si imposta la proprietà per tutte le colonne:

   for (int i = 0; i < dgv1.Columns.Count; i++)
   {
       // Permette al testo di andare a capo.
       dgv1.Columns[i].DefaultCellStyle.WrapMode = DataGridViewTriState.True;   
   }

  • Le righe del testo da inserire nella cella, vanno separate da 'Environment.NewLine'.
  • Esempio di testo nella cella della terza riga, seconda colonna (gli indici riga e colonna sono a base 0).

   dgv1.Rows[2].Cells[1].Value = "Ciao" + Environment.NewLine + "mondo!";


Celle lampeggianti in base al valore
  • Con il codice seguente, si vuole che le celle della DataGridView, lampeggino in base al valore della cella stessa.
  • Prima di tutto si carica una DataGridView con 5 colonne e 5 righe; in ogni cella viene inserito un valore numerico generato casualmente, compreso tra 1 e 100.
  • Il nome della DataGridView è dgvData. Si inserisca il codice seguente come evento in un Bottone o al caricamento della Form del progetto.

   dgvData.ColumnCount = 5;
   dgvData.RowCount = 5;

   Random Rnd = new Random();
   // Inserisce valori casuali nelle celle della DataGridView.
   for (int r = 0; r < dgvData.Rows.Count; r++)
   {
       for (int c = 0; c < dgvData.Columns.Count; c++)
       {
           int n = Rnd.Next(1, 101);
           dgvData.Rows[r].Cells[c].Value = n;
       }
   }

  • Si inseriscano nel progetto anche i seguenti controlli:
    • Un Timer, chiamato timClock.
    • Un Bottone, chiamato btnBlink, che attiva e disattiva il lampeggiamento.

   private void btnBlink_Click(object sender, EventArgs e)
   {
       timClock.Interval = 500;
       timClock.Enabled = !timClock.Enabled;
   }

  • Come si vede, il Bottone imposta solo l'intervallo del Timer e ne cambia lo stato, da abilitato a disabilitato e viceversa.
  • L'ultimo passo è quello di scrivere l'evento Tick del Timer, cioè il codice che viene mandato in esecuzione ogni volta che passa l'intervallo di tempo impostato nel Timer, in questo esempio 500 millisecondi.

   private void timClock_Tick(object sender, EventArgs e)
   {
       Color c1 = Color.White;
       Color c2 = Color.Yellow;

       // Cicla tutte le celle della DataGridView.
       for (int r = 0; r < dgvData.Rows.Count - 1; r++)
       {
           for (int c = 0; c < dgvData.Columns.Count - 1; c++)
           {
               if (Convert.ToInt32(dgvData.Rows[r].Cells[c].Value) <= 50)
               {
                   // Alterna il colore di sfondo.
                   if (dgvData.Rows[r].Cells[c].Style.BackColor == c1)
                       dgvData.Rows[r].Cells[c].Style.BackColor = c2;
                   else
                       dgvData.Rows[r].Cells[c].Style.BackColor = c1;
               }
           }
       }
   }

Celle colorate in base al valore
  • Nell'esempio successivo si colora una cella per ogni riga di una DataGridView in base al valore della cella stessa.
  • L'esempio è facilmente modificabile per colorare una cella in un'altra colonna o per implementare condizioni più complesse, per esempio basate sui valori di più celle.
  • Il semplice programma sotto ha una sola form che contiene la DataGridView con nome dgvData e un Button con nome Button1.
  • L'evento Click() del Button, definisce tre colonne per la DataGridView; poi vengono aggiunte cinque righe.

   private void button1_Click(object sender, EventArgs e)
   {
       // Imposta colonne della griglia.
       dgvData.Columns.Clear();

       DataGridViewTextBoxColumn col1 = new DataGridViewTextBoxColumn();
       col1.DataPropertyName = "Nome";
       col1.HeaderText = "Nome";
       col1.Name = "colNome";
       col1.ValueType = typeof(string);
       col1.Width = 100;
       col1.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleLeft;
      col1.ReadOnly = true;
       col1.MinimumWidth = 50;
       dgvData.Columns.Add(col1);

       DataGridViewTextBoxColumn col2 = new DataGridViewTextBoxColumn();
       col2.DataPropertyName = "Cognome";
       col2.HeaderText = "Cognome";
       col2.Name = "colCognome";
       col2.ValueType = typeof(string);
       col2.Width = 100;
       col2.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleLeft;
       col2.ReadOnly = true;
       col2.MinimumWidth = 50;
       dgvData.Columns.Add(col2);

       DataGridViewTextBoxColumn col3 = new DataGridViewTextBoxColumn();
       col3.DataPropertyName = "AnnoNascita";
       col3.HeaderText = "Anno Nascita";
       col3.Name = "colAnnoNascita";
       col3.ValueType = typeof(int);
       col3.Width = 100;
       col3.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
       col3.ReadOnly = true;
       col3.MinimumWidth = 50;
       dgvData.Columns.Add(col3);

       dgvData.Rows.Add(new object[] { "Pablo", "Picasso", 1881 });
       dgvData.Rows.Add(new object[] { "Gustave", "Klimt", 1862 });
       dgvData.Rows.Add(new object[] { "Salvador", "Dalì", 1904 });
       dgvData.Rows.Add(new object[] { "Amedeo", "Modigliani", 1884 });
       dgvData.Rows.Add(new object[] { "Andy", "Warhol", 1928 });
   }

  • La DataGridView ha l'evento RowsAdded() che viene generato ogni volta che si aggiunge una riga alla DataGridView.
  • In certi casi ho notato che l'evento viene generato due volte (in Internet si trova qualche caso) ma questo non crea particolari problemi.
  • Anche l'aggiunta della prima colonna con l'istruzione dgvData.Rows.Add(new object[] { "Pablo", "Picasso", 1881 }) genera l'evento.

   private void dgvData_RowsAdded(object sender, DataGridViewRowsAddedEventArgs e)
   {
       // Evita l'errore nel caso l'evento sia generato durante l'aggiunta delle colonne.
       if (dgvData.Columns.Count > 1)
       {
           // Colore cella.
           if (Convert.ToInt32(dgvData.Rows[e.RowIndex].Cells["colAnnoNascita"].Value) >= 1900)
           {
               // Giallo se l'anno di nascita è maggiore o uguale a 1900.
               dgvData.Rows[e.RowIndex].Cells["colAnnoNascita"].Style.BackColor = Color.Yellow;
           }
           else
           {
               // Rosso negli altri casi.
               dgvData.Rows[e.RowIndex].Cells["colAnnoNascita"].Style.BackColor = Color.Red;
           }
       }
   }

  • Ecco infine il risultato del codice precedente.



Celle colorate in base al valore - Alternativa
  • Nell'esempio successivo si colorano tutte le righe di una DataGridView in base a un valore RGB casuale.
  • L'esempio è facilmente modificabile per colorare una cella invece di tutte le celle anche implementando condizioni più complesse, per esempio basate sui valori di più celle.
  • Il semplice programma sotto ha una sola form che contiene la DataGridView con nome dgvData e un Button con nome Button1.
  • L'evento Click() del Button, definisce quattro colonne per la DataGridView; le prime tre colonne assumono un valore casuale compreso tra 0 e 255; rispettivamente sono la colonne "Red", la colonna "Green" e la colonna "Blue". La quarta colonna viene calcolata in base alle prime tre ed è il colore RGB espresso in notazione esadecimale. Sempre all'interno dell'evento, sono aggiunte 100 righe con le caratteristiche sopra espresse.

   private void button1_Click(object sender, EventArgs e)
   {
       // Imposta colonne della griglia.
       dgvData.Columns.Clear();

       DataGridViewTextBoxColumn col1 = new DataGridViewTextBoxColumn();
       col1.DataPropertyName = "Red";
       col1.HeaderText = "Red";
       col1.Name = "colRed";
       col1.ValueType = typeof(int);
       col1.Width = 100;
       col1.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
       col1.ReadOnly = true;
       col1.MinimumWidth = 50;
       dgvData.Columns.Add(col1);

       DataGridViewTextBoxColumn col2 = new DataGridViewTextBoxColumn();
       col2.DataPropertyName = "Green";
       col2.HeaderText = "Green";
       col2.Name = "colGreen";
       col2.ValueType = typeof(int);
       col2.Width = 100;
       col2.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
       col2.ReadOnly = true;
       col2.MinimumWidth = 50;
       dgvData.Columns.Add(col2);

       DataGridViewTextBoxColumn col3 = new DataGridViewTextBoxColumn();
       col3.DataPropertyName = "Blue";
       col3.HeaderText = "Blue";
       col3.Name = "colBlue";
       col3.ValueType = typeof(int);
       col3.Width = 100;
       col3.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
       col3.ReadOnly = true;
       col3.MinimumWidth = 50;
       dgvData.Columns.Add(col3);

       DataGridViewTextBoxColumn col4 = new DataGridViewTextBoxColumn();
       col4.DataPropertyName = "RGB";
       col4.HeaderText = "RGB";
       col4.Name = "colRGB";
       col4.ValueType = typeof(string);
       col4.Width = 100;
       col4.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleLeft;
       col4.ReadOnly = true;
       col4.MinimumWidth = 50;
       dgvData.Columns.Add(col4);

       // Carica le righe della griglia.
       Random r = new Random();
       for (int i = 0; i < 100; i++)
       {
           int red = r.Next(0, 256);
           int green = r.Next(0, 256);
           int blue = r.Next(0, 256);
           dgvData.Rows.Add(new object[] { red, green, blue, (red * 256 * 256 + green * 256 + blue).ToString("X") });
       }
   }

  • Il codice seguente va messo nell'evento RowPrePaint() della DataGridView.

   private void dgvData_RowPrePaint(object sender, DataGridViewRowPrePaintEventArgs e)
   {
       // Estrae le componenti RGB dalle celle.
       int red = Convert.ToInt32(((DataGridView)sender).Rows[e.RowIndex].Cells[0].Value);
       int green = Convert.ToInt32(((DataGridView)sender).Rows[e.RowIndex].Cells[1].Value);
       int blue = Convert.ToInt32(((DataGridView)sender).Rows[e.RowIndex].Cells[2].Value);
       // Imposta il colore della riga.
       dgvData.Rows[e.RowIndex].DefaultCellStyle.BackColor = Color.FromArgb(red, green, blue);
   }

  • Ecco infine il risultato del codice precedente.
  • Dato che ogni colore è generato casualmente, ogni esecuzione del programma darà un risultato diverso per ogni riga.



© 2022 Carlo Vecchio
Torna ai contenuti