You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何避免自定义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);
            }
        }
    }
}

修复说明

  1. 补充ControlStyles:
    • AllPaintingInWmPaint:将所有绘制操作合并到WM_PAINT消息,忽略WM_ERASEBKGND,减少背景闪烁
    • ResizeRedraw:控件大小变化时自动触发重绘,确保文本始终居中,避免手动调用Invalidate的频繁触发
    • SupportsTransparentBackColor:提升绘制兼容性,避免背景层冲突
  2. 重写OnPaintBackground:
    • 注释掉base调用,阻止系统默认的背景擦除,因为我们在OnPaint中已经完成了全部绘制
  3. 绘制细节优化:
    • 给进度填充区域添加2px边距,和原生ProgressBar视觉保持一致
    • 启用高质量平滑绘制,提升文本和图形的显示效果

内容的提问来源于stack exchange,提问作者Daniel Lip

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 05:40:16