今天写了一个可以显示进度条的ListView控件,代码如下: /// <summary> /// ListViewEx 的摘要说明。 /// </summary> public class ListViewEx : System.Windows.Forms.ListView { /// <summary> /// 必需的设计器变量。 /// </summary> private System.ComponentModel.Container components = null; private String mProgressColumnText = String.Empty; /// <summary> /// 需要设置为进度条的列标头文字,根据这些文字判断所在列是否为进度条显示列 /// </summary> private String ProgressColumnText { get { return mProgressColumnText; } set { mProgressColumnText = value; } } private Color mProgressColor = Color.Red; public Color ProgressColor { get { return this.mProgressColor; } set { this.mProgressColor = value; } } private Color mProgressTextColor = Color.Black; public Color ProgressTextColor { get { return mProgressTextColor; } set { mProgressTextColor = value; } } public ListViewEx() { SetStyle( ControlStyles.AllPaintingInWmPaint | ControlStyles.DoubleBuffer | ControlStyles.UserPaint | ControlStyles.ResizeRedraw, true); InitializeComponent(); // TODO: 在 InitializeComponent 调用后添加任何初始化 } public int ProgressColumIndex { set { progressIndex = value; } get { return progressIndex; } } int progressIndex = -1; /// <summary> /// 清理所有正在使用的资源。 /// </summary> protected override void Dispose( bool disposing ) { if( disposing ) { if(components != null) { components.Dispose(); } } base.Dispose( disposing ); } #region 组件设计器生成的代码 /// <summary> /// 设计器支持所需的方法 - 不要使用代码编辑器 /// 修改此方法的内容。 /// </summary> private void InitializeComponent() { // // ListViewEx // this.Name = "ListViewEx"; this.Size = new System.Drawing.Size(544, 392); this.Click += new System.EventHandler(this.ListViewEx_Click); this.Paint += new System.Windows.Forms.PaintEventHandler(this.ListViewEx_Paint); } #endregion const string numberstring = "0123456789."; private bool CheckIsFloat(String s) { foreach(char c in s) { if(numberstring.IndexOf(c) > -1) { continue; } else return false; } return true; } private void ListViewEx_Paint(object sender, System.Windows.Forms.PaintEventArgs e) { e.Graphics.Clear(this.BackColor);//清除显示类容 if(progressIndex == -1)//检索被设置为进度条的列 { for(int i=0;i<this.Columns.Count;i++) { if(this.Columns[i].Text == mProgressColumnText) { progressIndex = i;break; } } } for(int i=0;i<this.Items.Count;i++)//依次绘制每一行 { Rectangle rect = this.GetItemRect(i);//获取当前要绘制行的Rect if(rect.Top < 0 || rect.Top >= this.ClientRectangle.Height) continue; //不在显示范围内,跳过 if(rect != Rectangle.Empty) { int totalwidth = 0; //列宽记数,实际上就是当前要绘制列的X坐标 for(int j=0;j<this.Columns.Count;j++) { int currwidth = this.Columns[j].Width;//获取当前列宽度 Rectangle tmpRect = new Rectangle(totalwidth,rect.Top,currwidth,rect.Height);//生成当前subitem的外接矩形 if(j!= progressIndex) { //非进度条列 DrawString(tmpRect,this.Items[i].SubItems[j].Text,this.Columns[j].TextAlign,e.Graphics, this.Items[i].Selected); } else { //进度条列 if(CheckIsFloat(this.Items[i].SubItems[j].Text))//判断当前subitem文本是否可以转为浮点数 { float tmpf = float.Parse(this.Items[i].SubItems[j].Text); if(tmpf >= 1.0f) { tmpf = tmpf / 100.0f; } DrawProgress(tmpRect,tmpf,e.Graphics, this.Items[i].Selected); } } totalwidth += this.Columns[j].Width; } } } } //绘制非进度条列的subitem private void DrawString(Rectangle rect,String s,HorizontalAlignment aglin,Graphics g,bool isSelect) { StringFormat sf = new StringFormat(); switch(aglin) { case HorizontalAlignment.Center: sf.Alignment = StringAlignment.Center; break; case HorizontalAlignment.Left: sf.Alignment = StringAlignment.Near; break; case HorizontalAlignment.Right: sf.Alignment = StringAlignment.Far; break; } sf.LineAlignment = StringAlignment.Center; sf.Trimming = StringTrimming.EllipsisCharacter; if(!isSelect) g.DrawString(s,this.Font,Brushes.Black,rect, sf); else { g.FillRectangle(Brushes.RoyalBlue,rect); g.DrawString(s,this.Font,Brushes.White,rect, sf); } } ///绘制进度条列的subitem private void DrawProgress(Rectangle rect,float percent,Graphics g,bool isSelect) { if(rect.Height > 2 && rect.Width > 2) { if(rect.Top > 0 && rect.Top < this.Height && (rect.Left > this.Left && rect.Left < this.Width)) { //绘制进度 int width = (int)(rect.Width * percent); Rectangle newRect = new Rectangle(rect.Left + 1,rect.Top + 1,width - 2,rect.Height -2 ); using(Brush tmpb = new SolidBrush(this.mProgressColor)) { g.FillRectangle(tmpb, newRect); } if(!isSelect) g.DrawRectangle(Pens.Yellow,rect); else { newRect = new Rectangle(rect.Left + 1,rect.Top + 1,rect.Width-2,rect.Height - 2); g.DrawRectangle(Pens.RoyalBlue,newRect); } StringFormat sf = new StringFormat(); sf.Alignment = StringAlignment.Center; sf.LineAlignment = StringAlignment.Center; sf.Trimming = StringTrimming.EllipsisCharacter; newRect = new Rectangle(rect.Left + 1,rect.Top + 1,rect.Width-2,rect.Height - 2); using(Brush b = new SolidBrush(mProgressTextColor)) { g.DrawString(percent.ToString("p1"),this.Font,b,newRect, sf); } } } else return; } private void ListViewEx_Click(object sender, System.EventArgs e) { this.Invalidate(); } }

评论