Winforms平台界面开发技巧分享:如何使用渐变绘制进度条

点击“了解更多”获取DevExpressv19.2完整版下载
【Winforms平台界面开发技巧分享:如何使用渐变绘制进度条】DevExpressWinformsControls内置140多个UI控件和库 , 完美构建流畅、美观且易于使用的应用程序 。
问题:开发人员想要使用带有3中颜色的渐变来显示进度条 , 即开始、中间和末尾有3中不同的颜色 , 但目前只能使用property.startcolor和property.endcolor对两种颜色实现 , 没有可用的middlecolor属性 。 是否有办法或者可以使用那些控件来实现如下图所示的效果:
Winforms平台界面开发技巧分享:如何使用渐变绘制进度条
文章图片

解决办法:如果要绘制一些文本 , 则必须在进度行下为其留出空间 。 由于进度线始终占据整个空间 , 因此您需要更新所有必需矩形的高度 。 相关代码示例如下:
privatevoidprogressBarControl1_Paint(objectsender,PaintEventArgse){ProgressBarViewInfovi=(ProgressBarViewInfo)this.progressBarControl1.GetViewInfo();Paddingbt=CalcBorderThickness(vi);intprogressHeight=22;inttextIndent=2;vi.ProgressInfo.Bounds=UpdateHeight(vi.ProgressInfo.Bounds,progressHeight);vi.ProgressInfo.EmptyBounds=UpdateHeight(vi.ProgressInfo.EmptyBounds,progressHeight);vi.ProgressInfo.EmptyBounds2=UpdateHeight(vi.ProgressInfo.EmptyBounds2,progressHeight);vi.ProgressInfo.ProgressBounds=UpdateHeight(vi.ProgressInfo.ProgressBounds,progressHeight);Rectangleall=vi.ProgressInfo.Bounds;Rectanglefilled=vi.ProgressInfo.ProgressBounds;Rectanglepart1=newRectangle(filled.X,filled.Y,filled.Width/2+1,filled.Height);Rectanglepart2=newRectangle(part1.Right,filled.Y,filled.Right-part1.Right,filled.Height);using(GraphicsCachecache=newGraphicsCache(e.Graphics)){cache.Graphics.Clear(this.progressBarControl1.Parent.BackColor);RectangleborderBounds=vi.ProgressInfo.Bounds;borderBounds.Inflate(bt.Left,bt.Top);vi.ProgressInfo.Cache=cache;vi.BorderPainter.DrawObject(newObjectInfoArgs(){Bounds=borderBounds,Cache=cache});cache.FillRectangle(cache.GetGradientBrush(part1,Color.Red,Color.Yellow,LinearGradientMode.Horizontal),part1);cache.FillRectangle(cache.GetGradientBrush(part2,Color.Yellow,Color.Green,LinearGradientMode.Horizontal),part2);SizetextSize=vi.ProgressAppearance.CalcTextSize(cache,vi.DisplayText,-1).ToSize();intlinePos=part2.Right>=all.Right-1?all.Right-1:part2.Right;cache.DrawLine(cache.GetPen(Color.Black),newPoint(linePos,part2.Top),newPoint(linePos,part2.Bottom+textSize.Height+textIndent));RectangletextRect=newRectangle(newPoint(linePos+textIndent,part2.Bottom+textIndent),textSize);if(textRect.Right>all.Right)textRect.X-=textRect.Width+textIndent*2;vi.ProgressAppearance.DrawString(cache,vi.DisplayText,textRect);}}privatePaddingCalcBorderThickness(ProgressBarViewInfovi){SkinProgressBarObjectPainterp=newSkinProgressBarObjectPainter(vi.LookAndFeel);ProgressBarObjectInfoArgse=newProgressBarObjectInfoArgs(vi.Appearance);Rectangleclient=newRectangle(0,0,100,100);Rectangler=vi.BorderPainter.CalcBoundsByClientRectangle(vi.ProgressInfo,client);Paddingres=newPadding(client.X-r.X,client.Y-r.Y,r.Right-client.Right,r.Bottom-client.Bottom);returnres;}privateRectangleUpdateHeight(Rectanglebounds,intheight){bounds.Height=height;returnbounds;}ProgressBarControl控件不支持此功能 , 为了实现您的目标 , 建议使用ProgressBarControl.Paint事件并编写代码来绘制渐变进度条 , 示例如下:
privatevoidprogressBarControl1_Paint(objectsender,PaintEventArgse){ProgressBarViewInfovi=(ProgressBarViewInfo)this.progressBarControl1.GetViewInfo();Paddingbt=CalcBorderThickness(vi);intprogressHeight=22;inttextIndent=2;vi.ProgressInfo.Bounds=UpdateHeight(vi.ProgressInfo.Bounds,progressHeight);vi.ProgressInfo.EmptyBounds=UpdateHeight(vi.ProgressInfo.EmptyBounds,progressHeight);vi.ProgressInfo.EmptyBounds2=UpdateHeight(vi.ProgressInfo.EmptyBounds2,progressHeight);vi.ProgressInfo.ProgressBounds=UpdateHeight(vi.ProgressInfo.ProgressBounds,progressHeight);Rectangleall=vi.ProgressInfo.Bounds;Rectanglefilled=vi.ProgressInfo.ProgressBounds;Rectanglepart1=newRectangle(filled.X,filled.Y,filled.Width/2+1,filled.Height);Rectanglepart2=newRectangle(part1.Right,filled.Y,filled.Right-part1.Right,filled.Height);using(GraphicsCachecache=newGraphicsCache(e.Graphics)){cache.Graphics.Clear(this.progressBarControl1.Parent.BackColor);RectangleborderBounds=vi.ProgressInfo.Bounds;borderBounds.Inflate(bt.Left,bt.Top);vi.ProgressInfo.Cache=cache;vi.BorderPainter.DrawObject(newObjectInfoArgs(){Bounds=borderBounds,Cache=cache});cache.FillRectangle(cache.GetGradientBrush(part1,Color.Red,Color.Yellow,LinearGradientMode.Horizontal),part1);cache.FillRectangle(cache.GetGradientBrush(part2,Color.Yellow,Color.Green,LinearGradientMode.Horizontal),part2);SizetextSize=vi.ProgressAppearance.CalcTextSize(cache,vi.DisplayText,-1).ToSize();intlinePos=part2.Right>=all.Right-1?all.Right-1:part2.Right;cache.DrawLine(cache.GetPen(Color.Black),newPoint(linePos,part2.Top),newPoint(linePos,part2.Bottom+textSize.Height+textIndent));RectangletextRect=newRectangle(newPoint(linePos+textIndent,part2.Bottom+textIndent),textSize);if(textRect.Right>all.Right)textRect.X-=textRect.Width+textIndent*2;vi.ProgressAppearance.DrawString(cache,vi.DisplayText,textRect);}}privatePaddingCalcBorderThickness(ProgressBarViewInfovi){SkinProgressBarObjectPainterp=newSkinProgressBarObjectPainter(vi.LookAndFeel);ProgressBarObjectInfoArgse=newProgressBarObjectInfoArgs(vi.Appearance);Rectangleclient=newRectangle(0,0,100,100);Rectangler=vi.BorderPainter.CalcBoundsByClientRectangle(vi.ProgressInfo,client);Paddingres=newPadding(client.X-r.X,client.Y-r.Y,r.Right-client.Right,r.Bottom-client.Bottom);returnres;}privateRectangleUpdateHeight(Rectanglebounds,intheight){bounds.Height=height;returnbounds;}


    推荐阅读