C# 在listview 中添加进度条

来源:互联网 发布:花千骨网络播放量 编辑:程序博客网 时间:2024/04/30 06:42

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

原创粉丝点击