【问题标题】:How to fix progress-bar gradient along circular path?如何沿圆形路径修复进度条渐变?
【发布时间】:2013-12-01 21:03:34
【问题描述】:

现在我正在尝试沿圆形路径创建带有渐变的进度条,但渐变不是实心的,颜色之间的空间很小,如screenshot 中所示... 那么有什么问题以及如何解决它?

    public ExtProgressBar()
    {
        this.SetStyle(ControlStyles.OptimizedDoubleBuffer |
                      ControlStyles.AllPaintingInWmPaint |
                      ControlStyles.UserPaint,
                      true);

        _gradientColorList.Add(Color.Violet);
        _gradientColorList.Add(Color.Indigo);
        _gradientColorList.Add(Color.Blue);
        _gradientColorList.Add(Color.DodgerBlue);

        CreateGradientBrushList(ref _gradientColorList);
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        Image bmp = new Bitmap(this.Width, this.Height);
        Graphics g = Graphics.FromImage(bmp);
        g.SmoothingMode = SmoothingMode.AntiAlias;
        g.PixelOffsetMode = PixelOffsetMode.HighQuality;

        SolidBrush brushBase = new SolidBrush(this.BaseColor); //custom property
        SolidBrush brushBack = new SolidBrush(this.BackColor);
        SolidBrush brushFore = new SolidBrush(this.ForeColor);

        //base ellipse
        g.FillEllipse(brushBase, GetRectangle(0));

        //fallowing code block creates circular gradient
        int i = 0;
        float endAngle = 360f * this.Value / 100 - 90f;
        float sweepAngle = 360f / _gradientBrushList.Count;
        for (float startAngle = -90f; startAngle < endAngle; startAngle += sweepAngle)
        {
            if (i < _gradientBrushList.Count)
            {
                g.FillPie(_gradientBrushList[i++], GetRectangle(0), startAngle, sweepAngle);
            }
        }

        //back ellipse
        g.FillEllipse(brushBack, GetRectangle(this.Thickness));

        //draw value string in center of p-bar
        string value = this.Value.ToString();
        float fontSize = (float)(Math.Min(this.Width - this.Thickness * 2, this.Height - this.Thickness * 2) / 2);
        Font font = new Font("Calibri", (fontSize > 0 ? fontSize : 1), FontStyle.Bold, GraphicsUnit.Pixel);
        SizeF strLen = g.MeasureString(value, font);
        Point strLoc = new Point((int)((this.Width / 2) - (strLen.Width / 2)), (int)((this.Height / 2) - (strLen.Height / 2)));
        g.DrawString(value, font, brushFore, strLoc);

        e.Graphics.DrawImage(bmp, Point.Empty);
    }

    private Rectangle GetRectangle(int offset)
    {
        return new Rectangle(offset, offset, this.Width - offset * 2, this.Height - offset * 2);
    }

    private List<SolidBrush> _gradientBrushList = new List<SolidBrush>();

    private void CreateGradientBrushList(ref List<Color> _gradientColorList)
    {
        List<Color> gradientColorList = new List<Color>();

        foreach (Color color in _gradientColorList)
            gradientColorList.Add(color);

        for (int subdivideCount = 0; subdivideCount <= 3; subdivideCount++) //Smoothness
        {
            int i = 0;
            int gradientColorListCount = gradientColorList.Count - 1;
            while (i < gradientColorListCount)
            {
                gradientColorList.Insert(i + 1, GetMiddleColor(gradientColorList[i], gradientColorList[i + 1]));
                i += 2;
                gradientColorListCount++;
            }
        }

        foreach (Color color in gradientColorList)
            _gradientBrushList.Add(new SolidBrush(color));
    }

    private List<Color> _gradientColorList = new List<Color>();

    public List<Color> GradientColorList
    {
        get
        {
            return _gradientColorList; 
        }
        set
        {
            try
            {
                if (value == null)
                    throw new ArgumentNullException();
                if (value == null || value.Count < 2)
                    throw new Exception("Gradient color list count is less than 2.");
            }
            catch (Exception exp)
            {
                MessageBox.Show(exp.Message, "Exception caught", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning);
                _gradientColorList = value;
                CreateGradientBrushList(ref _gradientColorList);
            }
        }
    }

【问题讨论】:

    标签: c# winforms progress-bar gradient


    【解决方案1】:

    还可以将DrawPieFillPie 配对使用。 这是因为FillPie 方法只填充饼图部分的内部,而不是边界。 代码:

        protected override void OnPaint(PaintEventArgs e)
        {
            Image bmp = new Bitmap(this.Width, this.Height);
            Graphics g = Graphics.FromImage(bmp);
            g.SmoothingMode = SmoothingMode.AntiAlias;
            g.PixelOffsetMode = PixelOffsetMode.HighQuality;
    
            SolidBrush brushBase = new SolidBrush(this.BaseColor); //custom property
            SolidBrush brushBack = new SolidBrush(this.BackColor);
            SolidBrush brushFore = new SolidBrush(this.ForeColor);
    
            //base ellipse
            g.FillEllipse(brushBase, GetRectangle(0));
    
            //fallowing code block creates circular gradient
            int i = 0;
            float endAngle = 360f * this.Value / 100 - 90f;
            float sweepAngle = 360f / _gradientBrushList.Count;
            for (float startAngle = -90f; startAngle < endAngle; startAngle += sweepAngle)
            {
                if (i < _gradientBrushList.Count)
                {
                    g.DrawPie(_gradientPenList[i++], GetRectangle(0), startAngle, sweepAngle);
                    g.FillPie(_gradientBrushList[i++], GetRectangle(0), startAngle, sweepAngle);
                }
            }
    
            //back ellipse
            g.FillEllipse(brushBack, GetRectangle(this.Thickness));
    
            //draw value string in center of p-bar
            string value = this.Value.ToString();
            float fontSize = (float)(Math.Min(this.Width - this.Thickness * 2, this.Height - this.Thickness * 2) / 2);
            Font font = new Font("Calibri", (fontSize > 0 ? fontSize : 1), FontStyle.Bold, GraphicsUnit.Pixel);
            SizeF strLen = g.MeasureString(value, font);
            Point strLoc = new Point((int)((this.Width / 2) - (strLen.Width / 2)), (int)((this.Height / 2) - (strLen.Height / 2)));
            g.DrawString(value, font, brushFore, strLoc);
    
            e.Graphics.DrawImage(bmp, Point.Empty);
        }
    
        private Rectangle GetRectangle(int offset)
        {
            return new Rectangle(offset, offset, this.Width - offset * 2, this.Height - offset * 2);
        }
    
        private List<SolidBrush> _gradientBrushList = new List<SolidBrush>();
        private List<Pen> _gradientPenList = new List<Pen>();
    
        private void CreateGradientBrushList(ref List<Color> _gradientColorList)
        {
            List<Color> gradientColorList = new List<Color>();
    
            foreach (Color color in _gradientColorList)
                gradientColorList.Add(color);
    
            for (int subdivideCount = 0; subdivideCount <= 3; subdivideCount++) //Smoothness
            {
                int i = 0;
                int gradientColorListCount = gradientColorList.Count - 1;
                while (i < gradientColorListCount)
                {
                    gradientColorList.Insert(i + 1, GetMiddleColor(gradientColorList[i], gradientColorList[i + 1]));
                    i += 2;
                    gradientColorListCount++;
                }
            }
    
            foreach (Color color in gradientColorList)
            {
                _gradientBrushList.Add(new SolidBrush(color));
                _gradientPenList.Add(new Pen(color));
            }
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-05-10
      • 2015-03-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-22
      • 1970-01-01
      相关资源
      最近更新 更多