今天写了一个可以显示进度条的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();
}
}
评论