Работа с элементом ProgressBar в C#

User Rating: 4 / 5

Всем привет. В данной статье мы с вами разберём, как работать с элементом ProgressBar в C# и напишем тестовое приложение, демонстрирующее его работу.

В статье не будет рассказано про запуск какого-либо процесса и отражение хода его выполнения с помощью элемента ProgressBar, равно как и не рассматривается взаимодействие ProgressBar с элементом BackgroundWorker. Для этой цели есть отдельная статья: Пишем на C# программу для поиска файлов, используя ProgressBar и BackgroundWorker. В рамках текущей статьи рассматриваются совсем базовые свойства элемента ProgressBar и синтетический пример заполнения его индикатора вручную.

Элемент ProgressBar доступен среди набора стандартных элементов, предоставляемых в Windows Forms. Как следует из названия этого элемента, он используется для индикации состояния прогресса выполнения какого-то процесса. Например, это может быть копирование файлов, установка программы, выполнение какой-то фоновой задачи и так далее - здесь всё зависит от решаемой задачи, для которой необходимо использовать ProgressBar.

В проекте для Windows Forms элемент будет доступен на панели элементов, он выглядит так:

Мы напишем простое приложение для Windows Forms в среде разработки Microsoft Visual Studio, которое покажет основные возможности элемента ProgressBar. При старте нашего приложения будет происходить заполнение прогресса для какого-то абстрактного тестового процесса/задачи. Можно будет остановить процесс и вместе с ним заполнение прогресс бара, а также можно будет сбросить весь процесс и начать его сначала. Мы также будем выводить процент выполнения процесса и отображать некий текстовый статус в отдельных метках, чтобы пользователь программы понимал, что происходит с программой. Наконец, в поле "Шаг прогресс бара" мы сможем поменять шаг заполнения прогресс бара (шаг влияет на скорость продвижения индикатора прогресса). Выглядеть приложение будет следующим образом:

Начнём с создания нового проекта в среде разработки Microsoft Visual Studio. При прохождении шагов в мастере создания нового проекта выберем тип проекта "Приложение Windows Forms (.NET Framework)", а в качестве имени проекта выберем ProgressBarSample. Когда проект будет создан, выберем главную форму и в окне "Свойства" изменим её название со стандартного Form1 на FrmProgressBarSample:

Также поменяем название файла формы в окне "Обозреватель решений" - с предлагаемого по умолчанию имени Form1.cs мы переименуем класс в FrmProgressBarSample.cs. Для этого выберем файл класса главной формы и нажмём F2 (либо в контекстном меню выберем пункт меню "Переименовать"), затем введём новое название класса FrmProgressBarSample.cs. В итоге у нас должно получиться следующее:

Выделим главную форму в режиме конструктора и зададим ей следующие свойства:

  • StartPosition - CenterScreen
  • Size - 658; 180
  • FormBorderStyle - FixedSingle
  • Text - [Allineed.Ru] Пример работы с элементом ProgressBar
  • MaximizeBox - False
  • MinimizeBox - False

Теперь настало время разместить на главной форме приложения необходимые элементы управления, включая и сам ProgressBar.

Перетаскиваем на главную форму следующие элементы из панели элементов:

  • 1 элемент ProgressBar
  • 5 элементов Label
  • 2 элемента Button
  • 1 элемент ComboBox
  • 1 элемент Timer

Далее по очереди выберем каждый элемент, размещённый на форме и установим им следующие свойства:

элемент ProgressBar:

  • Name - ProgressBarProcess
  • Size - 616; 23
  • Location - 12; 21

1-я метка (с текстом "Выполнено"):

  • Name - LabelPercentComplete
  • Location - 9; 47
  • Text - Выполнено:

2-я метка (для отображения процента заполнения прогресс бара):

  • Name - LabelPercentCompleteText
  • Location - 82; 47
  • Text - %
  • Font - Microsoft Sans Serif; 8,25pt; style=Bold

3-я метка (с текстом "Статус"):

  • Name - LabelStatus
  • Location - 9; 69
  • Text - Статус:

4-я метка (для отображения статуса выполнения задачи):

  • Name - LabelStatusText
  • Location - 82; 69
  • Text - ?
  • Font - Microsoft Sans Serif; 8,25pt; style=Bold

5-я метка (с текстом "Шаг прогресс бара"):

  • Name - LabelProgressStep
  • Location - 328; 111
  • Text - Шаг прогресс бара:

1-я кнопка (с текстом "Сброс"):

  • Name - ButtonReset
  • Location - 13; 106
  • Size - 130; 23
  • Text - &Сброс

2-я кнопка (с текстом "Остановить"):

  • Name - ButtonStop
  • Location - 149; 106
  • Size - 130; 23
  • Text - &Остановить

элемент ComboBox:

  • Name - ComboBoxProgressStep
  • Location - 441; 108
  • Size - 121; 21
  • DropDownStyle - DropDownList

элемент Timer:

  • Name - TimerForProgressBar
  • Enabled - True
  • Interval - 1000

Окно конструктора формы с расположенными на ней элементами теперь должно выглядеть следующим образом:

 

Теперь перейдем к программированию элементов формы.

Дважды кликнем на форме, в результате чего мы перейдем к коду формы, и для нас будет сгенерирован метод с именем FrmProgressBarSample_Load для обработки события загрузки формы.

При загрузке формы мы хотим инициализировать наш выпадающий список "Шаг прогресс бара" какими-то предопределёнными значениями. Давайте создадим небольшой внутренний класс с именем ProgressStep, который будет отвечать за хранение пары значений - процент продвижения прогресс бара и соответствующее ему целочисленной значение. Добавим следующее объявление класса ProgressStep внутри класса формы FrmProgressBarSample:

public partial class FrmProgressBarSample : Form {

        class ProgressStep {
            public string StepText { get; set; }
            public int StepValue { get; set; }

            public ProgressStep(string stepText, int stepValue) {
                StepText = stepText;
                StepValue = stepValue;
            }

            public override string ToString() {
                return StepText;
            }
        }

        private void FrmProgressBarSample_Load(object sender, EventArgs e) {

        }
}

Как видим, внутри класса ProgressStep у нас есть два поля StepText (тип string) и StepValue (тип int). Также мы добавили в класс конструктор с параметрами, с помощью которого мы сможем быстро создавать объекты класса, передавая нужные нам значения. Заметим и то, что с помощью ключевого слова override мы переопределяем метод ToString() в классе, возвращая значение поля StepText - это нам необходимо для того, чтобы любые объекты класса ProgressStep, помещённые в элемент ComboBox на форме с именем ComboBoxProgressStep автоматически "умели" себя привести к строковому значению и вывести в выпадающем списка строковые значения вида "10%", "20%" и так далее.

Теперь где-нибудь ниже сгенерированного метода FrmProgressBarSample_Load напишем новый метод, который добавит 5 предопределённых значений процента в ComboBox. Назовём новый метод FillProgressSteps():

        private void FillProgressSteps() {            
            ComboBoxProgressStep.Items.Add(new ProgressStep("10%", 10));
            ComboBoxProgressStep.Items.Add(new ProgressStep("20%", 20));
            ComboBoxProgressStep.Items.Add(new ProgressStep("30%", 30));
            ComboBoxProgressStep.Items.Add(new ProgressStep("40%", 40));
            ComboBoxProgressStep.Items.Add(new ProgressStep("50%", 50));
        }

Этот метод по сути инициализирует доступные значения шага для нашего прогресс бара, которые легко можем поменять на форме.

Далее мы создадим ещё один метод UpdateProgressBarPercentComplete(), который будет обновлять текст в метке с именем LabelPercentCompleteText и будет выводить текущее значение процента выполнения. Значение текущего процента выполнения есть у нашего прогресс бара ProgressBarProcess, и оно хранится в специальном свойстве Value. Метод также будет проверять значение прогресса на попадание в определённые диапазоны значений и, в зависимости от этих диапазонов, будет менять текст в метке LabelStatusText, отражая статус текущего шага:

        private void UpdateProgressBarPercentComplete() {
            LabelPercentCompleteText.Text = ProgressBarProcess.Value + "%";
            if (ProgressBarProcess.Value >= 0 && ProgressBarProcess.Value < 20) {
                LabelStatusText.Text = "Инициализация...";
            } else if (ProgressBarProcess.Value >= 20 && ProgressBarProcess.Value < 40) {
                LabelStatusText.Text = "Подготовка примера...";
            } else if (ProgressBarProcess.Value >= 40 && ProgressBarProcess.Value < 60) {
                LabelStatusText.Text = "Выполнение задачи #1...";
            } else if (ProgressBarProcess.Value >= 60 && ProgressBarProcess.Value < 80) {
                LabelStatusText.Text = "Выполнение задачи #2...";
            } else if (ProgressBarProcess.Value >= 80 && ProgressBarProcess.Value < 100) {
                LabelStatusText.Text = "Почти готово, завершение...";
            } else {
                LabelStatusText.Text = "Выполнено.";
            }
        }

Теперь, когда методы готовы, мы вызовем их при загрузке нашей главной формы. Для этого просто добавим 2 строки кода в обработчик загрузки формы:

        private void FrmProgressBarSample_Load(object sender, EventArgs e) {
            UpdateProgressBarPercentComplete();
            FillProgressSteps();
        }

На этом этапе можем запустить форму и посмотреть на результат: мы увидим, что в выпадающем списке "Шаг прогресс бара" теперь доступны значения 10%, 20%, 30%, 40% и 50%, а напротив метки "Выполнено" увидим значение текущего прогресса - 0%.

Сделаем так, чтобы по при вызове события Tick таймера каждый раз выполнялся 1 шаг нашего прогресс бара. Для этого находим в конструкторе формы таймер TimerForProgressBar и дважды кликнем по нему. В результате в коде формы будет сгенерирован метод-обработчик TimerForProgressBar_Tick для таймера. Напишем в нём такой код:

        private void TimerForProgressBar_Tick(object sender, EventArgs e) {            
            ProgressBarProcess.PerformStep();
            UpdateProgressBarPercentComplete();

            ButtonStop.Enabled = ProgressBarProcess.Value != 100;
            if (ProgressBarProcess.Value >= 100) {
                TimerForProgressBar.Stop();
            }            
        }

С помощью вызова метода PerformStep() у прогресс бара выполняется увеличение на величину Step внутреннего значения прогресс бара, которое хранится в поле Value, а также производится отрисовка текущего прогресса.

Затем мы вызываем уже известный нам метод UpdateProgressBarPercentComplete(), который обновит процент выполненного прогресса и статус задачи.

Мы также регулируем доступность кнопки "&Остановить" - она доступна только тогда, когда значение прогресс бара не равно 100.

В последнем условии метода мы также проверяем поле ProgressBarProcess.Value - если оно больше или равно 100, то мы останавливаем сам таймер.

Теперь напишем код для наших кнопок "&Сброс" и "&Остановить". Дважды кликнем по каждой кнопке в конструкторе формы - будет сгенерированы методы ButtonStop_Click и ButtonReset_Click, которые наполним следующим кодом:

         private void ButtonStop_Click(object sender, EventArgs e) {
            if (TimerForProgressBar.Enabled) {
                TimerForProgressBar.Stop();                
                ButtonStop.Text = "&Продолжить";
            } else {
                TimerForProgressBar.Start();
                ButtonStop.Text = "&Остановить";
            }            
        }

        private void ButtonReset_Click(object sender, EventArgs e) {
            ProgressBarProcess.Value = 0;
            UpdateProgressBarPercentComplete();
            if (!TimerForProgressBar.Enabled) {
                TimerForProgressBar.Start();
            }
        }

Кнопка "&Остановить" и её метод-обработчик ButtonStop_Click проверяет текущее состояние таймера - если он включен, то таймер останавливаем и переименовываем название кнопки на "&Продолжить". И наоборот - если таймер выключен - запускаем его и переименовываем кнопку обратно в "&Остановить".

Кнопка "&Сброс" и её метод-обработчик ButtonReset_Click устанавливает значение прогресс бара в значение 0, а затем вызывает перерисовку процента выполнения и названия текущего шага - при помощи вызова метода UpdateProgressBarPercentComplete(). Также происходит проверка, что если таймер сейчас не включен, то мы его включаем для начала выполнения процесса.

Нам осталось последнее - при изменении индекса выбранного элемента в выпадающем ComboBox - получить выбранный элемент (это будет экземпляр нашего класса ProgressStep) и установить шаг для прогресс бара выбранным значением. Для этого на форме выберем ComboBox и дважды кликнем на нём. Сгенерируется метод-обработчик для события SelectedIndexChanged (оно происходит при смене индекса выбранного элемента), заполним его таким кодом:

        private void ComboBoxProgressStep_SelectedIndexChanged(object sender, EventArgs e) {
            if (ComboBoxProgressStep.SelectedItem != null) {
                ProgressStep step = (ProgressStep)ComboBoxProgressStep.SelectedItem;
                ProgressBarProcess.Step = step.StepValue;
            }
        }

На этом код нашего примера полностью готов. Запустим приложение и видим, как прогресс бар начинает постепенно заполняться, а напротив поля "Статус" изменяется текст с описанием выполняемого шага. Попробуем поиграть с формой - понажимаем кнопки "&Остановить" и "&Сброс" и посмотрим, как ведёт себя прогресс бар. Можем также изменять значение шага прогресса, чтобы ускорить/замедлить заполнение прогресс бара.

Проект с готовыми исходными кодами примера вы можете скачать в нашем каталоге по этой ссылке.

Яндекс.Метрика