/ Published in: C#
Features/Requirements:\r\n\r\n[1] lightweight, easy-to-add\r\n[2] Display progress of long operation using (a) progress bar and (b) user-text.\r\n[3] Close dialog upon (a) Normal completion of long operation or (b) Cancel button used for early cancellation of long operation\r\n[4] GUI not hung/hourglassing during long operation. This can be done using threads or DoEvents. This example uses the BackgroundWorker class as a member of a Form.\r\n[5] Synchronized with no race conditions.\r\n\r\nThe form displayed consists of three elements: label, progress bar and a cancel button. The label auto-sizes so that user text will be displayed. The application constructs the dialog with parameters for titlebar text and a delegate for the long operation. The long operation reports progress using BackgroundWorker.ReportProgress. The long operation checks for cancellation using BackgroundWorker.CancellationPending\r\n\r\nSee code for example usage.
Expand |
Embed | Plain Text
Copy this code and paste it in your HTML
// Example usage: private void button4_Click(object sender, EventArgs e) { // Create dialog. // Show dialog with Synchronous/blocking call. // LongOperation() is called by dialog. dlgProgress.ShowDialog(); // Synchronous/blocking call. } private void LongOperation(object sender, DoWorkEventArgs e) { BackgroundWorker worker = sender as BackgroundWorker; int max = 20; for (int i = 0; i < max; i++) { if (worker.CancellationPending) // See if cacel button was pressed. { System.Threading.Thread.Sleep(2000); // Similate time for clean-up. break; } int percent = i * 100 / max; string userState = percent.ToString(); // render a string to display on the progress dialog. // Append to string just to show multi-line user-status info. if (percent >= 45 && percent <= 55) { userState += "Half way"; } if (percent >= 85) { userState += "Almost done"; } worker.ReportProgress(percent, userState); // Report percent and user-status info to dialog. System.Threading.Thread.Sleep(800); // Simulate time-consuming operation } } // Implementation (in ProgressWithCancel.cs) namespace ProgressWithCancel { public partial class ProgressWithCancel : Form { public ProgressWithCancel(string whyWeAreWaiting, DoWorkEventHandler work) { InitializeComponent(); this.Text = whyWeAreWaiting; // Show in title bar backgroundWorker1.DoWork += work; // Event handler to be called in context of new thread. } private void btnCancel_Click(object sender, EventArgs e) { label1.Text = "Cancel pending"; backgroundWorker1.CancelAsync(); // Tell worker to abort. btnCancel.Enabled = false; } private void Progress_Load(object sender, EventArgs e) { backgroundWorker1.RunWorkerAsync(); } private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e) { progressBar1.Value = e.ProgressPercentage; label1.Text = e.UserState as string; } private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { Close(); } } } // Designer (in ProgressWithCancel.designer.cs) namespace ProgressWithCancel { partial class ProgressWithCancel { /// <summary> /// Required designer variable. /// </summary> private System.ComponentModel.IContainer components = null; /// <summary> /// Clean up any resources being used. /// </summary> /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param> protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Windows Form Designer generated code /// <summary> /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// </summary> private void InitializeComponent() { this.tableLayoutPanel1.SuspendLayout(); this.SuspendLayout(); // // tableLayoutPanel1 // this.tableLayoutPanel1.AutoSize = true; this.tableLayoutPanel1.ColumnCount = 1; this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F)); this.tableLayoutPanel1.Controls.Add(this.label1, 0, 0); this.tableLayoutPanel1.Controls.Add(this.btnCancel, 0, 2); this.tableLayoutPanel1.Controls.Add(this.progressBar1, 0, 1); this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill; this.tableLayoutPanel1.Name = "tableLayoutPanel1"; this.tableLayoutPanel1.RowCount = 3; this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F)); this.tableLayoutPanel1.TabIndex = 0; // // btnCancel // this.btnCancel.Anchor = System.Windows.Forms.AnchorStyles.Top; this.btnCancel.AutoSize = true; this.btnCancel.Name = "btnCancel"; this.btnCancel.TabIndex = 0; this.btnCancel.Text = "Cancel"; this.btnCancel.UseVisualStyleBackColor = true; // // progressBar1 // this.progressBar1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); this.progressBar1.Name = "progressBar1"; this.progressBar1.TabIndex = 1; // // backgroundWorker1 // this.backgroundWorker1.WorkerReportsProgress = true; this.backgroundWorker1.WorkerSupportsCancellation = true; this.backgroundWorker1.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(this.backgroundWorker1_RunWorkerCompleted); this.backgroundWorker1.ProgressChanged += new System.ComponentModel.ProgressChangedEventHandler(this.backgroundWorker1_ProgressChanged); // // label1 // this.label1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.label1.AutoSize = true; this.label1.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D; this.label1.Name = "label1"; this.label1.TabIndex = 1; this.label1.Text = "label1"; this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; // // Progress // this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.AutoSize = true; this.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; this.ControlBox = false; this.Controls.Add(this.tableLayoutPanel1); this.Name = "Progress"; this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; this.Text = "Progress"; this.tableLayoutPanel1.ResumeLayout(false); this.tableLayoutPanel1.PerformLayout(); this.ResumeLayout(false); this.PerformLayout(); } #endregion private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1; private System.Windows.Forms.Button btnCancel; public System.Windows.Forms.ProgressBar progressBar1; public System.ComponentModel.BackgroundWorker backgroundWorker1; private System.Windows.Forms.Label label1; } }