Let's consider a scenario wherein a user has some data in his/her grid and wishes to display the status of some data or a progress bar in one of the grid cells. For example, we need to show the status of some track records being copied to the memory or a user interface similar to that of Windows Media Player wherein the Current Status of the songs being copied is displayed via a progress bar. Here we can make use of ComponentOne C1TrueDBGrid for WinForms wherein complex cell customizations can be performed in OwnerDrawCell event of C1TrueDBGrid. The OwnerDrawCell event is used to customize the way each cell is rendered or override the painting completely. With this blog, we will implement scenario in C1TrueDBGrid.
Load the Track Record list into a DataSet and bind it with C1TrueDBGrid.
DataTable dt;
private void Form1_Load(object sender, System.EventArgs e)
{
// load data from resource
DataSet ds = GetDataSet("tracks.xsd");
// configure grid
this.c1TrueDBGrid1.MultiSelect = MultiSelectEnum.None;
this.c1TrueDBGrid1.MarqueeStyle = MarqueeEnum.NoMarquee;
this.c1TrueDBGrid1.AllowUpdate = false;
// bind grid
dt = ds.Tables[0];
this.c1TrueDBGrid1.DataSource = dt;
this.c1TrueDBGrid1.Columns["Status"].DataWidth = 160;
this.c1TrueDBGrid1.Splits[0].DisplayColumns["Status"].Width = 160;
this.c1TrueDBGrid1.Splits[0].DisplayColumns["Status"].OwnerDraw = true;
// create gdi objects
Color color = Color.HotPink;
_pen = new Pen(color, 1);
_bmp = new Bitmap(100, 20);
Rectangle rc = Rectangle.Empty;
rc.Size = _bmp.Size;
using (Graphics g = Graphics.FromImage(_bmp))
using (Brush b = new LinearGradientBrush(rc, Color.Transparent, color, LinearGradientMode.Horizontal))
{
g.FillRectangle(b, rc);
}
// start copying all songs right away
foreach (DataRow dr in ds.Tables[0].Rows)
_songs[dr] = DateTime.Now;
}
Display the Progress Bar in cells by handling the OwnerDrawCell event of the C1TrueDBGrid.
private void c1TrueDBGrid1_OwnerDrawCell(object sender, C1.Win.C1TrueDBGrid.OwnerDrawCellEventArgs e)
{
// Showing Progress Bar in Column 'Status'
if (this.c1TrueDBGrid1.Splits[0].DisplayColumns[e.Col].Name == "Status" && e.Row >= 0)
{
DataRow dr = dt.Rows[e.Row];
if (dr == null)
return;
// see if we're copying the song
if (!_songs.ContainsKey(dr))
return;
// calculate how much is done
DateTime start = (DateTime)_songs[dr];
TimeSpan elapsed = DateTime.Now - start;
TimeSpan length = (TimeSpan)dr["Length"];
int pct = (length.TotalSeconds > 0)
? (int)(elapsed.TotalSeconds / length.TotalSeconds * 100f * 20f)
: 100;
// song is done? remove from list
if (pct >= 100)
{
_songs.Remove(dr);
dr["Status"] = "Copied";
return;
}
// draw background
e.Style = this.c1TrueDBGrid1.Styles["HighlightRow"];
e.DrawCellFlags = C1.Win.C1TrueDBGrid.Styles.DrawCellFlags.All;
// progress bar outline
Rectangle rc = e.CellRect;
rc.Width--;
rc.Height--;
e.Graphics.DrawRectangle(_pen, rc);
// fill progress bar
rc = e.CellRect;
rc.Inflate(-2, -2);
rc.Width = rc.Width * pct / 100;
e.Graphics.DrawImage(_bmp, rc);
// draw text
// Create string to draw.
String drawString = string.Format("Copying ({0}% done)", pct);
// Create font and brush.
Font drawFont = new Font("Arial", 8);
SolidBrush drawBrush = new SolidBrush(Color.Black);
// Draw string to screen.
e.Graphics.DrawString(drawString, drawFont, drawBrush, e.CellRect.X,e.CellRect.Y);
e.DrawCellFlags = C1.Win.C1TrueDBGrid.Styles.DrawCellFlags.All;
e.Handled = true;
}
}