C# でプログレス バーを作成する

Syed Hassan Sabeeh Kazmi 2023年10月12日
  1. Windows フォーム アプリ (.NET Framework) で進行状況バーを作成する
  2. C#BackgroundWorker クラスを使用してプログレス バーを作成する
  3. C# でテキスト付きのプログレス バーを作成する
C# でプログレス バーを作成する

時間のかかるファイル操作と計算には進行状況の表示が必要です。進行状況バーは、実行時間の長い操作中にユーザーに進行状況情報を表示する最良の方法です。 このチュートリアルでは、Visual Studio 2022 を使用して C# で 3つの異なる進行状況バーを作成する方法を説明します。

C# の動的プログレス バーには、範囲を指定する 2つのプロパティ (Maximum プロパティと Minimum プロパティ) があり、主にコピーするファイルまたは実行するプロセスの数に相当します。 さらに、プロセスが完了し、プログレス バーの値をインクリメントする場合は、PerformStep メソッドで Step プロパティを使用します。

C# の事前に設計されたプログレス バーは、水平方向にのみ配置できます。 ただし、ニーズに合わせてカスタム プログレス バーを作成できます。 進行状況バーの主な目的は、C# アプリケーションによって現在実行中のタスクの進行状況についてユーザーに警告することです。

Windows フォーム アプリ (.NET Framework) で進行状況バーを作成する

進行状況バーは、操作の進行状況を示すユーザー インターフェイス要素として機能します。 C# のプログレス バーは、進行状況を表す 2つのモード (不確定モードと連続モード) をサポートしています。

プログレス バーの不確定モードは、どれくらい時間がかかるかわからないタスクや操作を実行するときに便利です。 これは、C# アプリケーションがまだユーザーに応答している間に、(通常は BackgroundWorker クラスの助けを借りて) バックグラウンド スレッドにデータを非同期的にロードすることによって行われます。

データの読み込み中に不確定な進行状況バーを表示し、実際の進行状況が始まるまで設定するのは、一般的な設計パラダイムです。 WinForms でプログレス バーを作成する場合、プログレス バーの Style プロパティを Marquee に設定することが重要です。

ただし、WPM のプログレス バーには、Style に似た Isdeterminate プロパティがあり、True としての値は Marquee と同様に機能します。

// namespaces for C# windows application (.NET Framework)

using System;
using System.Windows.Forms;

namespace ProgressBarExp {
  public partial class Form1 : Form {
    public Form1() {
      InitializeComponent();
    }

    // create a `progressBar1` progress bar in your C# project design
    private void progressBar1_Click(object sender, EventArgs e) {}

    // create a method that performs some calculations
    // the progress bar will synch with this method and progress accordingly
    private void Caluculate(int i) {
      // perform a task
    }

    // create a `RunOperation` button to perform calculations or take action in your C# project
    // design
    private void RunOperation_Click(object sender, EventArgs e) {
      // set the visibility of progress bar
      progressBar1.Visible = true;

      for (int j = 0; j < 10000001; j++) {
        Caluculate(j);
        if (j == 10000000) {
          MessageBox.Show("Operation Complete!");
          progressBar1.Visible = false;
        }
      }
    }
    private void Form1_Load(object sender, EventArgs e) {
      // for indeterminate progress using .NET framework
      progressBar1.Style = ProgressBarStyle.Marquee;

      progressBar1.Visible = false;
    }
  }
}

出力:

Windows フォームの C# プログレス バー - 出力 1

プログレス バーは、データが読み込まれるときに進行状況を報告する場合にのみ、その目的を正しく果たします。 C# アプリケーションでは、プログレス バーはソフトウェアのインストール、時間のかかるタスクの実行、および起動によく使用されるため、ユーザーはプロセスにかかる時間と残りの進行状況を正確に把握できます。

C# で継続的なプログレス バーを作成するには、RunOperation_Click イベントからコードを削除し、次のコードに置き換えます。

private void RunOperation_Click(object sender, EventArgs e) {
  progressBar1.Visible = true;
  progressBar1.Maximum = 10000000;
  progressBar1.Value = 1;

  for (int j = 0; j < 10000001; j++) {
    Caluculate(j);

    if (progressBar1.Value == 10000000) {
      MessageBox.Show("Operation Complete!");
      progressBar1.Visible = false;
      break;
    }

    // it will measure the progress of the task or operations and progress in regards to the
    // completion of a task It only requires if the progress bar style is not set to Marquee
    progressBar1.PerformStep();
  }
}

出力:

Windows フォームの C# プログレス バー - 出力 2

Form1_Load イベントで、progressBar1.Style = ProgressBarStyle.Marquee; をコメント化します。 C# コードの行で、タスクの完了率 % に応じて継続的な進行状況バーが表示されます。

C#BackgroundWorker クラスを使用してプログレス バーを作成する

C# アプリケーションでプログレス バーを使用することがいかに簡単かは明らかです。 ここで、静的な値だけでなく、実際の作業と同期することによって、プログレス バーがどのように前進するかを調べます。

ほとんどの新しい C# 開発者が問題に遭遇するのは、同じスレッドでタスクを実行し、進行状況バーを同時に更新できないことに気付いたときです。 C# アプリケーションのユーザー インターフェイス スレッドで負荷の高いタスクを実行し、それに応じて進行状況バーを更新しようとしている場合、C# の BackgroundWorker クラスのサービスが必要です。

BackgroundWorker クラスの助けがなければ、プログレス バーがほとんど役に立たなくなります。 進行状況バーには、タスクが正常に完了するまで進行状況の更新は表示されず、バックグラウンド ワーカーが単一のスレッドで両方を同時に更新する必要があります。

これは、C# で動作するバックグラウンドでプログレス バーを作成してワーカー スレッドでタスクを実行し、更新をユーザー インターフェイス スレッドにプッシュする理想的な方法です。これにより、プログレス バーが即座に更新され、これらの更新が表示されます。

using System;
using System.Windows;
using System.Threading;
using System.Windows.Forms;
using System.ComponentModel;

namespace ProgressBarExp {
  public partial class Form1 : Form {
    public Form1() {
      InitializeComponent();
    }

    // create a progress bar in your C# project's Form1.cs [Design]
    private void progressBar1_Click(object sender, EventArgs e) {}

    // a button to perform an operation synched with the `progressBar1`
    private void RunOperation_Click(object sender, EventArgs e) {
      BackgroundWorker taskSynch = new BackgroundWorker();
      taskSynch.WorkerReportsProgress = true;
      taskSynch.DoWork += taskSynch_DoWork;
      taskSynch.ProgressChanged += taskSynch_ProgressChanged;
      taskSynch.RunWorkerAsync();
    }

    // Form1 load event
    private void Form1_Load(object sender, EventArgs e) {}

    // create a method that connects `BackgroundWorker` with a task
    void taskSynch_DoWork(object sender, DoWorkEventArgs e) {
      for (int i = 0; i < 100; i++) {
        (sender as BackgroundWorker).ReportProgress(i);
        Thread.Sleep(100);
      }
    }

    // create a method that connects a task with the `progressBar1`
    void taskSynch_ProgressChanged(object sender, ProgressChangedEventArgs e) {
      progressBar1.Value = e.ProgressPercentage;
    }
  }
}

出力:

BackgroundWorker を使用した C# プログレス バー - 出力

C# でテキスト付きのプログレス バーを作成する

一般に、構成をより詳細に制御できるカスタム プログレス バーを作成できます。 ただし、プログレス バーを作成するために C# コードをゼロから作成するのは時間のかかる作業です。 Syncfusion UI ControlShellProgressBar などの NuGet パッケージを使用して、素晴らしいデザインのすぐに使用できるプログレス バーを取得できます。

テキスト付きのプログレス バーを作成する最も簡単な方法は、ラベルを使用し、タスクの進行状況に応じてテキストを変更することです。 その進行をタスクの進行と同期させることができます。

using System;
using System.Threading;
using System.Windows.Forms;
using System.ComponentModel;
using System.Drawing;

namespace ProgressBarExp {
  public partial class Form1 : Form {
    public Form1() {
      InitializeComponent();
    }

    private void RunOperation_Click(object sender, EventArgs e) {
      BackgroundWorker taskSynch = new BackgroundWorker();
      taskSynch.WorkerReportsProgress = true;
      taskSynch.DoWork += taskSynch_DoWork;
      taskSynch.ProgressChanged += taskSynch_ProgressChanged;
      taskSynch.RunWorkerAsync();
    }

    private void Form1_Load(object sender, EventArgs e) {
      // make the percentage label `backcolor` transparent
      label1.BackColor = Color.Transparent;
    }

    void taskSynch_DoWork(object sender, DoWorkEventArgs e) {
      for (int i = 0; i < 101; i++) {
        (sender as BackgroundWorker).ReportProgress(i);
        Thread.Sleep(100);

        // to support multi-threading for label1 and label 2
        if (label1.InvokeRequired) {
          label1.Invoke(new MethodInvoker(delegate {
            // shows the progression, it is syched with the task progression
            label1.Text = "Progress: " + i + "%";
          }));
        }

        if (label2.InvokeRequired) {
          label2.Invoke(new MethodInvoker(delegate {
            if (i < 25) {
              label2.Text = "Starting the task...";
            } else if (i > 25 && i < 50) {
              label2.Text = "Half way through...";
            } else if (i > 50 && i < 99) {
              label2.Text = "The wait will be over soon...";
            } else if (i == 100) {
              label2.Text = "Task is completed successfully!";
            }
          }));
        }
      }
    }

    void taskSynch_ProgressChanged(object sender, ProgressChangedEventArgs e) {
      // it will update the progress bar in real time depends on the progress of a task
      progressBar1.Value = e.ProgressPercentage;
    }
  }
}

出力:

テキスト付きの C# プログレス バー - 出力

この C# コードを実行する前に、C# プロジェクトの Form1 [Design]progressBar1 プログレス バー、Run Operation ボタン、および label1label2 ラベルを作成する必要があります。

このチュートリアルでは、C# の BackgroundWorker クラスを使用して、さまざまな種類のプログレス バーを作成し、それらをタスクの実際の進行状況と同期させる方法を学びました。

Syed Hassan Sabeeh Kazmi avatar Syed Hassan Sabeeh Kazmi avatar

Hassan is a Software Engineer with a well-developed set of programming skills. He uses his knowledge and writing capabilities to produce interesting-to-read technical articles.

GitHub

関連記事 - Csharp WinForms