In questi giorni avevo necessità di avere una ProgressBar in una DataGridView (System.Windows.Forms)... ho guardato in rete ma non trovavo nulla o nulla che mi piacesse. Usare componenti avanzate di terze parti per una misera ProgressBar mi sembrava eccessivo. Implementare qualcosa io!? Mumble c'è poca documentazione di come implementare una custom DataGridViewColumn e inoltre troppo tempo da spendere per lo specifico progetto. Occorre ragionare su vie alternative ma allo stesso tempo non mi volevo arrendere... è stato necessario un intenso ritiro spirituale ma dopo la fase sciacquone ecco la fumata bianca della giornata: lavorare sulle DataGridViewImageColumn e come si usa fare sul web sfruttare gli eventi di injection del "binding", come ItemDataBound per le web griglie, per la personalizzazione delle singole celle.
L'idea è quindi quella che negli opportuni eventi della DataGridView - che dipendono dai casi d'uso - avrei disegnato io l'immagine da associare alla griglia. Al primo giro mi sono implementato un veloce ProgressBarPainter che mi avrebbe aiutato a disegnare un rettangolo colorato di dimensioni diverse in base ai contesti...
public static class ProgressBarPainter
{
public static void Paint(Graphics g, int w, int h, double percentage)
{
int progressWidth = Convert.ToInt32(percentage * w);
g.FillRectangle(Brushes.Blue, 0, 0, progressWidth, h);
}
}
Poi ecco che la casualità e l'intellisense mi mostrano il nome di un interessante componente: ProgressBarRenderer ("Provides methods used to render a progress bar control with visual style"). Fantastico, la ProgressBarRender fa quello che deve/avrebbe dovuto fare il mio ProgressBarPainter, lo fa anche meglio ed è integrato/disponibile nel Framework! Ecco quindi una prima applicazione pratica dell'idea nell'implementazione dell'evento "RowsAdded" della DataGridView.
private void dgvJobList_RowsAdded(object sender, DataGridViewRowsAddedEventArgs e)
{
for (int index = e.RowIndex; index < e.RowCount; index++)
{
//Recupero cella dove disegnare la progressbar ...
DataGridViewRow gridViewRow = dgvJobList.Rows[e.RowIndex];
DataGridViewImageCell imageCell =
(DataGridViewImageCell)gridViewRow.Cells[percentageCompleted.Index];
//Recupero elemento bindato con la riga ...
JobInfoItem item = (JobInfoItem) gridViewRow.DataBoundItem;
//Creo l'immagine e disegno la progress bar ...
Bitmap image = new Bitmap(imageCell.Size.Width, imageCell.Size.Height);
Graphics g = Graphics.FromImage(image);
Rectangle progressBounds =
new Rectangle(0, 0, Convert.ToInt32(item.percentageCompleted * image.Width), image.Height);
ProgressBarRenderer.DrawHorizontalChunks(g, progressBounds);
imageCell.Value = image;
}
}
posted @ giovedì 20 aprile 2006 13:58