【C#】進捗状況ダイアログを表示しよう その2
heych.hatenablog.com
前回のはちょっと例が悪かったため、改めて進捗状況を表示するダイアログを作ってみたいと思います。
時間のかかる処理を作成する
- 新しいプロジェクトの作成
- Windows フォームアプリケーション(.NET Framework)を選択
- 作成
- TextBoxとButtonを配置し、ButtonのTextを「処理開始」に書き換える
- Buttonをダブルクリックし、コードを記述
BackgroundWorker bw = new BackgroundWorker(); public Form1() { InitializeComponent(); bw.WorkerSupportsCancellation = true; bw.WorkerReportsProgress = true; bw.DoWork += Bw_DoWork; bw.ProgressChanged += Bw_ProgressChanged; bw.RunWorkerCompleted += Bw_RunWorkerCompleted; } private void Bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { if (e.Cancelled) { MessageBox.Show("キャンセルしました。"); } else { MessageBox.Show("処理が完了しました。"); } } private void Bw_ProgressChanged(object sender, ProgressChangedEventArgs e) { //今は何もしない } private void Bw_DoWork(object sender, DoWorkEventArgs e) { var sum = 0; for (int i = 0; i <= 100; i++) { sum += i; if (bw.CancellationPending) { e.Cancel = true; break; } System.Threading.Thread.Sleep(100); bw.ReportProgress(i); this.Invoke((MethodInvoker)delegate () { textBox1.Text = sum.ToString(); }); } } private void button1_Click(object sender, EventArgs e) { bw.RunWorkerAsync(); }
しれっと使ってますが、MessageBoxというのは様々なメッセージダイアログを表示するクラスです。
プログレスバーダイアログを作成する
- フォームを追加
- 追加
- LabelとProgreassBarとButtonを追加してButtonのTextを「キャンセル」に設定
- Form2のプロパティ「ControlBox」を「False」に「StartPosition」を「CenterParent」に「FormBorderStyle」を「FixedDialog」に設定する
- Buttonをダブルクリックしてコードを書く
public string Title { get { return this.Text; } set { if (InvokeRequired) { this.Invoke((MethodInvoker)delegate () { this.Text = value; }); } else { this.Text = value; } } } public string Message { get { return label1.Text; } set { if (InvokeRequired) { this.Invoke((MethodInvoker)delegate () { label1.Text = value; }); } else { label1.Text = value; } } } public int Value { get { return progressBar1.Value; } set { if (InvokeRequired) { this.Invoke((MethodInvoker)delegate () { progressBar1.Value = value; }); } else { progressBar1.Value = value; } } } public BackgroundWorker Worker { get; set; } public Form2() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { Worker.CancelAsync(); }
InvokeRequiredはそのままで、Invokeが必要な場合Trueになります。
再びForm1のコードを書く
BackgroundWorker bw = new BackgroundWorker(); Form2 progressBarDialog; public Form1() { InitializeComponent(); bw.WorkerSupportsCancellation = true; bw.WorkerReportsProgress = true; bw.DoWork += Bw_DoWork; bw.ProgressChanged += Bw_ProgressChanged; bw.RunWorkerCompleted += Bw_RunWorkerCompleted; } private void Bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { progressBarDialog.Close(); if (e.Cancelled) { MessageBox.Show("キャンセルしました。"); } else { MessageBox.Show("処理が完了しました。"); } } private void Bw_ProgressChanged(object sender, ProgressChangedEventArgs e) { progressBarDialog.Value = e.ProgressPercentage; progressBarDialog.Message = e.ProgressPercentage + "% 完了しました。"; } private void Bw_DoWork(object sender, DoWorkEventArgs e) { var sum = 0; for (int i = 0; i <= 100; i++) { sum += i; if (bw.CancellationPending) { e.Cancel = true; break; } System.Threading.Thread.Sleep(100); bw.ReportProgress(i); this.Invoke((MethodInvoker)delegate () { textBox1.Text = sum.ToString(); }); } } private void button1_Click(object sender, EventArgs e) { progressBarDialog = new Form2(); progressBarDialog.Worker = bw; progressBarDialog.Title = "処理中"; progressBarDialog.Message = "処理を開始しました。"; progressBarDialog.Value = 0; progressBarDialog.Show(); bw.RunWorkerAsync(); }
このようにすることで、進捗状況の表示や処理のキャンセルを行う事ができます。