设想一下这样的一个场景,一个用户在他/她的网格内有一些数据,希望在某一个单元格展示某些数据的状态或进度条。
比如,需要显示一些被拷贝到内存或是类似于windows媒体播放器的用户界面的音轨录音的状态,而被拷贝的这些歌曲的当前状态通过进度条来显示。
这个时候,可以使用WinForms 的ComponentOne C1TrueDBGrid,用C1TrueDBGrid的OwnerDrawCell事件实现复杂单元格的用户自定义。OwnerDrawCell事件被用来定制每一个单元格呈现的方式或是彻底重载画面。在本博客中,用C1TrueDBGrid实现该场景。
加载数据
加载数据集到音轨录音表,并用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; }
在单元格中显示进度条
通过处理C1TrueDBGrid的OwnerDrawCell事件把进度条显示在网格单元中。
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; } }
源代码如下: