如何避免自定义ProgressBar(进度条)出现闪烁问题?
解决自定义ProgressBar控件持续闪烁的问题
你的自定义ProgressBar闪烁问题,核心是缺少必要的控件样式配置,以及系统默认背景重绘机制导致的冲突。以下是具体修复方案:
关键修改点
- 补充启用更多ControlStyles,彻底关闭不必要的系统重绘操作
- 重写
OnPaintBackground方法,避免默认背景擦除引发的闪烁 - 优化绘制细节,提升视觉一致性
修改后的完整代码
using System; using System.Drawing; using System.Drawing.Drawing2D; using System.Windows.Forms; namespace Lightnings_Detector { public partial class CustomProgressBar : UserControl { public CustomProgressBar() { InitializeComponent(); // 启用完整的双缓冲和自定义绘制样式 SetStyle(ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer | ControlStyles.ResizeRedraw | ControlStyles.SupportsTransparentBackColor, true); UpdateStyles(); this.Height = 23; } private int _progressValue = 0; public int ProgressValue { get => _progressValue; set { _progressValue = Math.Max(0, Math.Min(100, value)); Invalidate(); } } private string _progressText = ""; public string ProgressText { get => _progressText; set { _progressText = value; Invalidate(); } } // 重写该方法阻止系统默认背景擦除 protected override void OnPaintBackground(PaintEventArgs e) { // 不调用base方法,避免背景闪烁 } protected override void OnPaint(PaintEventArgs e) { // 开启高质量绘制优化 e.Graphics.SmoothingMode = SmoothingMode.HighQuality; e.Graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit; // 绘制进度条背景框架 ProgressBarRenderer.DrawHorizontalBar(e.Graphics, ClientRectangle); // 绘制进度填充区域(保留2px边距,对齐原生控件视觉) if (ProgressValue > 0) { var fillRect = new Rectangle(ClientRectangle.X + 2, ClientRectangle.Y + 2, (int)((ClientRectangle.Width - 4) * ((double)ProgressValue / 100)), ClientRectangle.Height - 4); ProgressBarRenderer.DrawHorizontalChunks(e.Graphics, fillRect); } // 绘制居中文本 using (var sf = new StringFormat { Alignment = StringAlignment.Center, LineAlignment = StringAlignment.Center }) { e.Graphics.DrawString(ProgressText, Font, Brushes.Black, ClientRectangle, sf); } } } }
修复说明
- 补充ControlStyles:
AllPaintingInWmPaint:将所有绘制操作合并到WM_PAINT消息,忽略WM_ERASEBKGND,减少背景闪烁ResizeRedraw:控件大小变化时自动触发重绘,确保文本始终居中,避免手动调用Invalidate的频繁触发SupportsTransparentBackColor:提升绘制兼容性,避免背景层冲突
- 重写OnPaintBackground:
- 注释掉base调用,阻止系统默认的背景擦除,因为我们在OnPaint中已经完成了全部绘制
- 绘制细节优化:
- 给进度填充区域添加2px边距,和原生ProgressBar视觉保持一致
- 启用高质量平滑绘制,提升文本和图形的显示效果
内容的提问来源于stack exchange,提问作者Daniel Lip
相关产品推荐
相关产品推荐

