过去一段时间,在研究Windows的系统控件ProgressBar,一直奇怪为啥它不能显示进度值,本以为是个很简单的问题,结果搜索很久,也没有找到好的解决方案,最后终于找到一个Perfect方案,特记录一下。
<一>比较蹩脚的方案:
用户自定义控件,在系统的ProgressBar上面放一个Label,在每次进度改变时,修改Label上的Text。
蹩脚的地方:有很明显的强制植入感觉,系统控件的透明色Transparent也不是真正透明的,Label在ProgressBar上,可以很明显的感觉到就像一坨屎丢在了大马路上,很显眼。
<二>比较完美的方案
集成系统ProgressBar,重新绘制,在每次进度改变的时候,刷新一次即可,并且可以修改滚动条的方向:水平滚动条或者垂直滚动条。代码如下:
1 public class ProgressBarWithValue : ProgressBar 2 { 3 private ProgressBarDirection direction = ProgressBarDirection.Horizontal; 4 private bool showPercent = true; 5 private string customText; 6 7 public ProgressBarWithValue() 8 { 9 SetStyle(ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer, true); 10 base.Size = new Size(200, 15); 11 } 12 13 protected override void OnPaint(PaintEventArgs e) 14 { 15 Rectangle rect = ClientRectangle; 16 Graphics g = e.Graphics; 17 if (direction == ProgressBarDirection.Horizontal) 18 ProgressBarRenderer.DrawHorizontalBar(g, rect); 19 else 20 ProgressBarRenderer.DrawVerticalBar(g, rect); 21 rect.Inflate(-3, -3); 22 if (Value > 0) 23 { 24 if (direction == ProgressBarDirection.Horizontal) 25 { 26 Rectangle clip = new Rectangle(rect.X, rect.Y, (int)Math.Round(((float)Value / Maximum) * rect.Width), rect.Height); 27 ProgressBarRenderer.DrawHorizontalChunks(g, clip); 28 } 29 else 30 { 31 int height = (int)Math.Round(((float)Value / Maximum) * rect.Height); 32 Rectangle clip = new Rectangle(rect.X, rect.Y + (rect.Height - height), rect.Width, height); 33 ProgressBarRenderer.DrawVerticalChunks(g, clip); 34 } 35 } 36 37 string text = showPercent ? (Value.ToString() + '%') : CustomText; 38 39 if (!string.IsNullOrEmpty(text)) 40 using (Font f = new Font(FontFamily.GenericSerif, 10)) 41 { 42 SizeF len = g.MeasureString(text, f); 43 Point location = new Point(Convert.ToInt32((Width / 2) - len.Width / 2), Convert.ToInt32((Height / 2) - len.Height / 2)); 44 g.DrawString(text, f, Brushes.Red, location); 45 } 46 } 47 48 49 ///50 /// 进度条方向,水平或者垂直 51 /// 52 public ProgressBarDirection Direction 53 { 54 get { return direction; } 55 set 56 { 57 if (direction != value) 58 { 59 direction = value; 60 Invalidate(); 61 } 62 } 63 } 64 65 ///66 /// 是否显示进度,true表示显示进度,否则显示自定义的字符串 67 /// 68 public bool ShowPercent 69 { 70 get { return showPercent; } 71 set 72 { 73 showPercent = value; 74 } 75 } 76 77 ///78 /// 自定义需要显示的字符串 79 /// 80 public string CustomText 81 { 82 get { return customText; } 83 set 84 { 85 if (customText != value) 86 { 87 customText = value; 88 if (!showPercent) 89 Invalidate(); 90 } 91 } 92 } 93 } 94 95 public enum ProgressBarDirection 96 { 97 ///98 /// 垂直方向 99 /// 100 Vertical,101 ///102 /// 水平方向103 /// 104 Horizontal,105 }
参考地址: