对于我正在制作的应用程序,我根据 William Daniel 制作的进度条制作了一个自定义进度条:How to Change the color of Progressbar in C# .NET 3.5?
用较低的百分比值进行一些测试后,我注意到这种奇怪的闪烁:
我尝试将
DoubleBuffered
设置为 true,但它们仍然出现。
有谁知道为什么会出现这些奇怪的线条?
这不是“闪烁”,这是一种“撕裂”。自定义控件并不总是完全绘制;如果您有一个闭环不允许表单正确地重新绘制自身及其子控件,则可能会发生这种情况。
可能的话,使填充 ProgressBar 的过程异步。
一些建议的修改使其更流畅
:
使用浮点值进行计算(不要转换为
int
删除位图并设置ControlStyles.OptimizedDoubleBuffer
如果为 true,则控件首先绘制到缓冲区而不是直接绘制到屏幕,这可以减少闪烁。如果你设置了这个
属性设置为 true,您还应该将 AllPaintingInWmPaint
然后当然设置
ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint
:
AllPaintingInWmPaint
:如果为 true,则控件会忽略窗口消息 WM_ERASEBKGND
以减少闪烁。 仅当 UserPaint 位设置为 true 时才应应用此样式。
UserPaint
:如果为真,则控件绘制自身而不是绘制控件 操作系统这样做。如果为 false,则不会引发 Paint 事件。 此样式仅适用于从 Control 派生的类。
ControlStyles.Opaque
完成其工作,以填充 ProgressBar 的基本图形。
根据当前设置的Value
float width = (this.Width - 3) * ((float)this.Value / this.Maximum)
width > 0
为绘图添加一些抗锯齿功能,设置Graphics.SmoothingMode,以使LinearGradientBrush
生成的颜色过渡更平滑。当您设置 LinearGradientMode.Horizontal 时,这会更有用。 结果:
作为一个小改进,您可以在进度条的顶部绘制一条 9 像素高、半透明颜色的线,以模拟原始的。更改代码添加
Graphics.DrawLine()
:
// [...]
using (var brush = new LinearGradientBrush(rect, BackColor, ForeColor, LinearGradientMode.Horizontal))
using (var pen = new Pen(Color.FromArgb(40, 240,240,240), 9)) {
e.Graphics.FillRectangle(brush, rect);
e.Graphics.DrawLine(pen, 1.0f, 1.0f, width, 1.0f);
}