C# 使用GDI+实现ProgressBar控件美化换肤
- 摘要:本文介绍C#使用GDI+重绘ProgressBar控件,实现了仿WIN7样式的进度条控件,并且可以自定义显示进度条完成进度的文字信息,跟以前不同的是,本文尝试使用BufferedGraphics来就实现双缓冲绘制。
ProgressBar控件跟上一文介绍的TrackBar控件一样,并没有提供一个方法可以方便的实现重绘,需要自己重载WM_PAINT消息来实现重绘。先来看看最终实现的效果:
为了让ProgressBar控件可以显示进度完成的信息,添加了一个属性:FormatString来格式化进度条完成信息,通过这个属性,可以定义自己需要显示什么样式的信息,默认为:{0:0.0%},即显示:50.0%。来看看类视图:
ProgressBar控件的绘制需要处理两种样式,一种是连续的显示((ProgressBarStyle.Continuous),一种是不停的滚动显示(ProgressBarStyle.Marquee)。绘制没有什么特别难的地方,就是需要自己计算已完成进度对应的控件的位置,绘制滚动样式的的时候,需要通过一个定时器(Timer)定时改变滚动条的位置和刷新控件。特别的是,这次利用BufferedGraphics来实现双缓冲,效果也还不错。ProgressBar控件主要是通过DrawProgressBar函数来绘制的,来看看这个函数的代码:
private void DrawProgressBar(IntPtr hWnd)
{
Graphics g = _bufferedGraphics.Graphics;
Rectangle rect = new Rectangle(Point.Empty, Size);
ProgressBarColorTable colorTable = ColorTable;
![]()
bool bBlock = Style != ProgressBarStyle.Marquee || base.DesignMode;
float basePosition = bBlock ? .30f : .45f;
![]()
SmoothingModeGraphics sg = new SmoothingModeGraphics(g);
![]()
RenderHelper.RenderBackgroundInternal(
g,
rect,
colorTable.TrackBack,
colorTable.Border,
colorTable.InnerBorder,
RoundStyle.All,
8,
basePosition,
true,
true,
LinearGradientMode.Vertical);
![]()
Rectangle trackRect = rect;
trackRect.Inflate(-2, -2);
![]()
if (bBlock)
{
trackRect.Width = (int)(((double)Value / (Maximum - Minimum)) * trackRect.Width);
![]()
RenderHelper.RenderBackgroundInternal(
g,
trackRect,
colorTable.TrackFore,
colorTable.Border,
colorTable.InnerBorder,
RoundStyle.All,
8,
basePosition,
false,
true,
LinearGradientMode.Vertical);
![]()
if (!string.IsNullOrEmpty(_formatString))
{
TextRenderer.DrawText(
g,
string.Format(_formatString, (double)Value / (Maximum - Minimum)),
base.Font,
rect,
base.ForeColor,
TextFormatFlags.VerticalCenter |
TextFormatFlags.HorizontalCenter |
TextFormatFlags.SingleLine |
TextFormatFlags.WordEllipsis);
}
}
else
{
GraphicsState state = g.Save();
![]()
g.SetClip(trackRect);
![]()
trackRect.X = _trackX;
trackRect.Width = MarqueeWidth;
![]()
using (GraphicsPath path = new GraphicsPath())
{
path.AddEllipse(trackRect);
g.SetClip(path, CombineMode.Intersect);
}
![]()
RenderHelper.RenderBackgroundInternal(
g,
trackRect,
colorTable.TrackFore,
colorTable.Border,
colorTable.InnerBorder,
RoundStyle.None,
8,
basePosition,
false,
false,
LinearGradientMode.Vertical);
![]()
using (LinearGradientBrush brush = new LinearGradientBrush(
trackRect, colorTable.InnerBorder, Color.Transparent, 0f))
{
Blend blend = new Blend();
blend.Factors = new float[] { 0f, 1f, 0f };
blend.Positions = new float[] { 0f, .5f, 1f };
brush.Blend = blend;
![]()
g.FillRectangle(brush, trackRect);
}
![]()
g.Restore(state);
}
![]()
sg.Dispose();
![]()
IntPtr hDC = NativeMethods.GetDC(hWnd);
_bufferedGraphics.Render(hDC);
NativeMethods.ReleaseDC(hWnd, hDC);
}
ProgressBar控件的美化就为你介绍到这里,希望对你了解ProgressBar控件的美化换肤有所帮助。
声明:
本文版权归作者和CS 程序员之窗所有,欢迎转载,转载必须保留以下版权信息,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
作者:Starts_2000
出处:CS 程序员之窗 http://www.csharpwin.com。
你可以免费使用或修改提供的源代码,但请保留源代码中的版权信息,详情请查看:
CS程序员之窗开源协议 http://www.csharpwin.com/csol.html。


Graphics g 
}
}