C#: Custom ProgressBar или меняем цвет у прогресс бара

Вопрос «Как поменять цвет полоски у ProgressBar» достаточно частый для языка C#. На самом деле не знаю почему разработчики .NET не добавили свойство изменения цвета полоски на другой — а ведь штука то на самом деле нужная. Так же не плохой была бы возможность отображения текущего прогресса в процентах или относительно какого либо числа, например 5 из 1000. Сегодня я решил поделиться с Вами набросками прогресса который может менять цвет полоски и отображать текущий прогресс в виде текста в двух вариантах: проценты и текущее значение относительно максимального значения.

К сожалению то, о чем я сейчас Вам говорю нельзя реализовать с помощью стандартного контрола ProgressBar. Поэтому если Вы хотите поменять цвет полоски, то Вам нужно будет писать свой прогресс бар. Я не буду вдаваться в подробности о том как создавать свой собственный control. Об это я уже говорил в данном посте. Так же я не буду наводить красоту в нашем разрабатываемом контроле, а остановлюсь лишь на минимальном функционале. Если Вы захотите как-то украсить наш control, то без проблем сможете это сделать, например добавив градиенты и т.п.

Сейчас я приведу листинг нашего ProgressBar который может менять цвет полоски, а затем опишу как им пользоваться:

using System;
using System.Drawing;
using System.Windows.Forms;

namespace FsLib
{
    class FsProgressBar: Control
    {
        public enum FsProgressTextType
        {
            AsIs, Percent
        }

        //Cal when Value was changed
        public event EventHandler ValueChanged;
        //Call when Value == MaxValue
        public event EventHandler ValuesIsMaximum;

        private Int32 minValue;
        public Int32 MinValue 
        {
            get 
            {
                return this.minValue;
            }
            set
            {
                if (value >= this.MaxValue)
                {
                    throw new Exception("MinValue must be less than MaxValue");
                }
                this.minValue = value;
                this.Invalidate();
            }
        }
        
        private Int32 maxValue;
        public Int32 MaxValue 
        {
            get
            {
                return this.maxValue;
            }
            set
            {
                if (value <= this.MinValue)
                {
                    throw new Exception("MaxValue must be more than MinValue");
                }
                this.maxValue = value;
                this.Invalidate();
            }
        }

        private Int32 value;
        public Int32 Value
        {
            get
            {
                return this.value;
            }
            set
            {
                if (value < this.MinValue || value > this.maxValue)
                {
                    throw new Exception("Value must be between MinValue and MaxValue");
                }
                this.value = value;
                if (this.value == this.MaxValue && this.ValuesIsMaximum != null)
                {
                    this.ValuesIsMaximum(this, new EventArgs());
                }
                if (this.ValueChanged != null)
                {
                    this.ValueChanged(this, new EventArgs());
                }
                this.Invalidate();
            }
        }

        private Int32 borderWidth;
        public Int32 BorderWidth
        {
            get
            {
                return this.borderWidth;
            }
            set
            {
                if (value < 0)
                {
                    throw new Exception("Border width can not be negative");
                }
                this.borderWidth = value;
            }
        }
        
        public System.Drawing.Color BorderColor { get; set; }
        public System.Drawing.Color ProgressColor { get; set; }
        public Boolean ShowProgressText { get; set; }
        public FsProgressTextType ProgressTextType { get; set; }

        public FsProgressBar()
        {
            SetStyle(ControlStyles.UserPaint, true);
            SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
            SetStyle(ControlStyles.SupportsTransparentBackColor, true);
            this.minValue = 0;
            this.maxValue = 100;
            this.value = 0;
            this.BorderWidth = 0;
            this.BorderColor = Color.Black;
            this.BackColor = SystemColors.Control;
            this.ForeColor = Color.Black;
            this.ProgressColor = Color.Yellow;
            this.ShowProgressText = true;
            this.Paint += new PaintEventHandler(FsProgressBar_Paint);
            this.Size = new Size(200, 30);
            this.ProgressTextType = FsProgressTextType.AsIs;
        }

        protected void FsProgressBar_Paint(object sender, PaintEventArgs e)
        {
            e.Graphics.FillRectangle(new SolidBrush(this.BackColor), new Rectangle(0, 0, this.Width, this.Height));
            e.Graphics.FillRectangle(new SolidBrush(this.ProgressColor), new Rectangle(0, 0, (this.Value * this.Width) / this.MaxValue, this.Height));
            if (this.BorderWidth > 0)
            {
                e.Graphics.DrawRectangle(new Pen(this.BorderColor, this.BorderWidth), this.DisplayRectangle);
            }
            if (this.ShowProgressText)
            {
                string text = String.Empty;
                switch (this.ProgressTextType)
                {
                    case FsProgressTextType.AsIs:
                        text = this.Value + " / " + this.MaxValue;
                        break;
                    case FsProgressTextType.Percent:
                        text = ((this.Value * 100) / this.MaxValue).ToString() + "%";
                        break;
                }
                System.Drawing.SizeF size = e.Graphics.MeasureString(text, this.Font);
                e.Graphics.DrawString(text, this.Font, new SolidBrush(this.ForeColor), new PointF(this.Width / 2 - size.Width / 2, this.Height / 2 - size.Height / 2)); 
            }
        }
    }
}

Чтобы создать данный контрол Вам нужно написать следующий код:

FsLib.FsProgressBar fsProgress = new FsLib.FsProgressBar();

Рассмотрим основные свойства нашего объекта:
fsProgress.ForeColor — Цвет отображаемого текста;
fsProgress.Font — Стиль отображаемого текста;
fsProgress.ProgressTextType — Как отображать текст прогресса (проценты или текущее значение);
fsProgress.ShowProgressText — Нужно ли отображать текст прогресса;
fsProgress.BackColor — Цвет фона;
fsProgress.ProgressColor — Цвет полоски прогресса;
fsProgress.BorderColor — Цвет рамки;
fsProgress.BorderWidth — Ширина рамки;
fsProgress.MinValue — Минимальное значение;
fsProgress.MaxValue — Максимальное значение;
fsProgress.Value — Текущее значение прогресса;

Рассмотрим основные события:
fsProgress.ValuesChanged — Вызывается при изменении значения;
fsProgress.ValuesIsMaximum — Вызывается если значение прогресса достигло максимума;

Запись опубликована в рубрике C# с метками , , , , , , , , , , , , , . Добавьте в закладки постоянную ссылку.