scene
Implementation of pop-up progress bar in Winform
To create a new form, add a progress bar control to the form, and then report the loading progress to the
Progress bar control.
Note:
Blog home page:
https://blog.csdn.net/badao_liumang_qizhi
Pay attention to the public address
Domineering procedural ape
Get programming related ebooks, tutorials and free downloads.
Realization
Design progress bar form
Create a new form FrmProgressBar, open the design page, and open the devoxpress toolbox.
Drag and drop a SplashScreen control
Then drag and drop a label and MarqueeProgressBarControl control
Then open its code page and edit its code as
public partial class FrmProgressBar : SplashScreen { #region Singleton implementation private static string _lockFlag = "FrmProgressBarLock"; private static FrmProgressBar _instance = null; /// <summary> /// Progress bar window instance /// </summary> public static FrmProgressBar Instance { get { lock(_lockFlag) { if (_instance == null) { _instance = new FrmProgressBar(true); } else if (_instance.IsDisposed) { _instance = null; _instance = new FrmProgressBar(true); } return _instance; } } } #endregion #region Field definition private bool _isShowTitle = false; #endregion #region Construction method private FrmProgressBar() { InitializeComponent(); } private FrmProgressBar(bool isShowTitle) { InitializeComponent(); this._isShowTitle = isShowTitle; this.marqueeProgressBarControl1.Properties.ShowTitle = this._isShowTitle; } #endregion #region Attribute definition /// <summary> /// Show title or not /// </summary> public bool IsShowTitle { get { return this._isShowTitle; } set { this._isShowTitle = value; this.marqueeProgressBarControl1.Properties.ShowTitle = this._isShowTitle; } } /// <summary> /// Prompt text /// </summary> public string NotifyText { get { return this.labelControl2.Text; } set { this.labelControl2.Text = value; } } /// <summary> /// Progress value /// </summary> public int ProgressValue { get { return (int)this.marqueeProgressBarControl1.EditValue; } set { this.marqueeProgressBarControl1.Text = String.Format("{0}%", value); } } #endregion #region Overrides public override void ProcessCommand(Enum cmd, object arg) { base.ProcessCommand(cmd, arg); } #endregion public enum SplashScreenCommand { } }
Call progress bar form
A new thread is needed to execute the task represented by the progress bar, in the event triggering the progress bar
BackgroundWorker bgWorker = new BackgroundWorker();
And set whether it reports progress property to true
bgWorker.WorkerReportsProgress = true;
Then bind the task represented by the specific progress bar
bgWorker.DoWork -= backgroundWorker1_DoWork;
bgWorker.DoWork += backgroundWorker1_DoWork;
Specific tasks will be performed in this bound method
Then set the event binding for task progress change
bgWorker.ProgressChanged -= bgWorker_ProgressChanged;
bgWorker.ProgressChanged += bgWorker_ProgressChanged;
In this method, the progress bar is bound to the task execution progress
private void bgWorker_ProgressChanged(object sender, ProgressChangedEventArgs e) { if (e.ProgressPercentage >= 0 && e.ProgressPercentage <= 100) { Dialog.FrmProgressBar.Instance.ProgressValue = e.ProgressPercentage; } }
Then close the progress bar window after the task is completed
bgWorker.RunWorkerCompleted -= bgWorker_RunWorkerCompleted;
bgWorker.RunWorkerCompleted += bgWorker_RunWorkerCompleted;
In the finished method
private void bgWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { Dialog.FrmProgressBar.Instance.Dispose(); //Close progress dialog }
Then start the background operation
bgWorker.RunWorkerAsync();
And finally let the progress bar form display
Dialog.FrmProgressBar.Instance.ShowDialog();
It should be noted that:
In the specific execution tasks bound in DoWork, they must be time-consuming tasks, if they are simple
Several for loops will not work, because there is no time difference between the two threads, they will be displayed and closed at the same time.
Therefore, in the specific background tasks to be executed, tasks with time difference should be executed, such as reading large data files.
And when performing this task, report according to the progress of the task.
In the method bound by DoWork
BackgroundWorker bgWorker = sender as BackgroundWorker; . . . bgWorker.ReportProgress(10); //10% . . . bgWorker.ReportProgress(65); . . . bgWorker.ReportProgress(100);
Full sample code
//Create a new background thread BackgroundWorker bgWorker = new BackgroundWorker(); //Set whether the thread reports progress to true bgWorker.WorkerReportsProgress = true; //The method of binding specific background tasks, in which progress will be reported bgWorker.DoWork -= backgroundWorker1_DoWork; bgWorker.DoWork += backgroundWorker1_DoWork; //When the progress changes, the event binding takes the bound progress as the progress of the progress bar bgWorker.ProgressChanged -= bgWorker_ProgressChanged; bgWorker.ProgressChanged += bgWorker_ProgressChanged; //The background thread will close the progress bar window after executing the event binding bgWorker.RunWorkerCompleted -= bgWorker_RunWorkerCompleted; bgWorker.RunWorkerCompleted += bgWorker_RunWorkerCompleted; //Start background operation bgWorker.RunWorkerAsync(); //Show progress bar window Dialog.FrmProgressBar.Instance.ShowDialog();
How to perform background tasks
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) { BackgroundWorker bgWorker = sender as BackgroundWorker; List<Cycle> cycles = null; List<Step> steps = null; List<Record> mainRecords = null; bgWorker.ReportProgress(10); //10% #region Load cycle data string cycleDataFile = String.Format("{0}{1}", Global.Instance.CurrDataFile, Global.CYCLE_EXT); if (System.IO.File.Exists(cycleDataFile)) { using (System.IO.Stream fs = new System.IO.FileStream(cycleDataFile, System.IO.FileMode.Open, System.IO.FileAccess.Read)) { cycles = ProtoBuf.Serializer.Deserialize<List<Cycle>>(fs); } } bgWorker.ReportProgress(40); #endregion #region Load step data string stepDataFile = String.Format("{0}{1}", Global.Instance.CurrDataFile, Global.STEP_EXT); if (System.IO.File.Exists(stepDataFile)) { using (System.IO.Stream fs = new System.IO.FileStream(stepDataFile, System.IO.FileMode.Open, System.IO.FileAccess.Read)) { steps = ProtoBuf.Serializer.Deserialize<List<Step>>(fs); } } bgWorker.ReportProgress(70); #endregion #region Load main channel data string mainRecordDataFile = String.Format("{0}{1}", Global.Instance.CurrDataFile, Global.MAIN_EXT); if (System.IO.File.Exists(mainRecordDataFile)) { using (System.IO.Stream fs = new System.IO.FileStream(mainRecordDataFile, System.IO.FileMode.Open, System.IO.FileAccess.Read)) { mainRecords = ProtoBuf.Serializer.Deserialize<List<Record>>(fs); } } #endregion bgWorker.ReportProgress(100); }
Background task progress change event
private void bgWorker_ProgressChanged(object sender, ProgressChangedEventArgs e) { if (e.ProgressPercentage >= 0 && e.ProgressPercentage <= 100) { Dialog.FrmProgressBar.Instance.ProgressValue = e.ProgressPercentage; } }
Background task execution completion event
private void bgWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { Dialog.FrmProgressBar.Instance.Dispose(); //Close progress dialog }