123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320 |
- using PTMedicalInsurance.Variables;
- using System;
- using System.Collections.Generic;
- using System.ComponentModel;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- using System.Windows.Forms;
- namespace PTMedicalInsurance.Common
- {
- public class ProgressDialog : Form
- {
- private ProgressBar progressBar1;
- private Label labelStatus;
- private Button cancelButton;
- BackgroundWorker _backgroundWorker;
- private int maximum;
- private ProgressBarStyle _pbStyle = ProgressBarStyle.Marquee;
- private string _header = "正在查询...";
- private int _marqueeAnimationSpeed = 50;
- public string HeaderText
- {
- get { return _header; }
- set { this.Text =_header = value; }
- }
- public ProgressBarStyle PBStyle
- {
- get { return _pbStyle; }
- set { progressBar1.Style =_pbStyle = value; }
- }
- public int MQSpeed
- {
- get { return _marqueeAnimationSpeed; }
- set { progressBar1.MarqueeAnimationSpeed =_marqueeAnimationSpeed = value; }
- }
- public ProgressDialog()
- {
- Init();
- }
- public ProgressDialog(BackgroundWorker backgroundWorker)
- {
- Init();
- _backgroundWorker = backgroundWorker;
- }
- private void Init()
- {
- Application.EnableVisualStyles();
- this.Text = _header;
- this.StartPosition = FormStartPosition.CenterParent;
- this.FormBorderStyle = FormBorderStyle.FixedDialog;
- this.MaximizeBox = false;
- this.MinimizeBox = false;
- this.ShowInTaskbar = false;
- this.TopMost = true; // 确保进度条始终在最前面
- this.CenterToScreen();
- progressBar1 = new ProgressBar
- {
- Location = new System.Drawing.Point(12, 12),
- Size = new System.Drawing.Size(260, 23)
- };
- //progressBar1.Style = ProgressBarStyle.Continuous;
- progressBar1.Style = _pbStyle;
- progressBar1.MarqueeAnimationSpeed = _marqueeAnimationSpeed;
- Controls.Add(progressBar1);
- labelStatus = new Label
- {
- Location = new System.Drawing.Point(12, 41),
- Size = new System.Drawing.Size(260, 23)
- };
- Controls.Add(labelStatus);
- //// 初始化取消按钮
- //cancelButton = new Button
- //{
- // Text = "取消",
- // Location = new System.Drawing.Point(197, 41), // 设置适当的位置
- // Size = new System.Drawing.Size(75, 23) // 设置按钮大小
- //};
- //cancelButton.Click += CancelButton_Click; // 添加点击事件处理程序
- //Controls.Add(cancelButton);
- // 初始化取消按钮
- cancelButton = new Button
- {
- Text = "取消",
- Location = new System.Drawing.Point(197, 60), // 修改Y坐标以避免与labelStatus重叠
- Size = new System.Drawing.Size(75, 23) // 设置按钮大小
- };
- cancelButton.Click += CancelButton_Click; // 添加点击事件处理程序
- Controls.Add(cancelButton);
- // 设置默认样式
- SetStyle(ControlStyles.ResizeRedraw, true);
- ClientSize = new System.Drawing.Size(284, 100);
- }
- // 允许外部设置进度条的值
- public int ProgressValue
- {
- set { if (InvokeRequired) Invoke(new Action(() => progressBar1.Value = value)); else progressBar1.Value = value; }
- }
- public void UpdateProgress(int progress)
- {
- //if (progressBar1.InvokeRequired)
- //{
- // progressBar1.Invoke(new Action<int>(UpdateProgress), progress);
- //}
- //else
- //{
- // progressBar1.Value = progress;
- // //这个有点糊涂了,这个进度条显示总是少一个
- // labelStatus.Text = $"已完成 {progress}/{maximum}";
- //}
- this.Invoke((MethodInvoker)delegate
- {
- progressBar1.Value = progress;
- //这个有点糊涂了,这个进度条显示总是少一个
- labelStatus.Text = $"已完成 {progress}/{maximum}";
- ///在Windows Forms应用程序中,控件的更新通常是由操作系统消息循环处理的。当你修改一个控件的属性(如 Text 或 Value),
- ///这些更改并不会立即反映在界面上,而是会被放入队列等待下一个合适的时机进行绘制。这是因为直接更新控件属性并不会强制执行重绘操作,
- ///系统可能会批量处理多个更新以提高效率。
- ///使用 Refresh() 方法 调用控件的 Refresh() 方法会强制该控件立即重绘自身。这包括清除控件并重新绘制其所有内容
- if (progress == maximum)
- {
- progressBar1.Refresh();
- labelStatus.Refresh();
- }
-
- });
- }
- public void SetProgress(int max)
- {
- maximum = max;
- progressBar1.Maximum = maximum;
- }
- // 允许外部设置状态文本
- public string StatusText
- {
- set { if (InvokeRequired) Invoke(new Action(() => labelStatus.Text = value)); else labelStatus.Text = value; }
- }
- //异步展示
- public async void ShowAsync()
- {
- await Task.Run(() => progressBar1.Show());
- }
- private void CancelButton_Click(object sender, EventArgs e)
- {
- // 这里可以放置取消操作的逻辑
- // 比如通知BackgroundWorker取消工作
- if (_backgroundWorker != null && _backgroundWorker.WorkerSupportsCancellation)
- {
- _backgroundWorker.CancelAsync();
- }
- this.Close(); // 关闭对话框
- }
- }
- public class DataLoader : IDisposable
- {
- private BackgroundWorker _backgroundWorker = new BackgroundWorker();
- public delegate int MyFunc<T1>(out T1 err,ProgressCallback progressCallback);
- private MyFunc<string> _delegateFunc;
- private ProgressDialog progressDialog ;
- private Form mainForm;
- // 定义进度回调委托
- public delegate void ProgressCallback(int progress);
- public DataLoader(MyFunc<string> delegateFunc, Form frm)
- {
- mainForm = frm;
- _delegateFunc = delegateFunc ?? throw new ArgumentNullException(nameof(delegateFunc));
-
- // 配置 BackgroundWorker
- _backgroundWorker.WorkerReportsProgress = true;
- _backgroundWorker.WorkerSupportsCancellation = true;
- _backgroundWorker.DoWork += BackgroundWorker_DoWork;
- _backgroundWorker.RunWorkerCompleted += BackgroundWorker_RunWorkerCompleted;
- _backgroundWorker.ProgressChanged += BackgroundWorker_ProgressChanged;
- progressDialog = new ProgressDialog(_backgroundWorker);
- }
- public DataLoader(Form frm)
- {
- mainForm = frm;
- // 配置 BackgroundWorker
- _backgroundWorker.WorkerReportsProgress = true;
- _backgroundWorker.WorkerSupportsCancellation = true;
- _backgroundWorker.DoWork += BackgroundWorker_DoWork;
- _backgroundWorker.RunWorkerCompleted += BackgroundWorker_RunWorkerCompleted;
- _backgroundWorker.ProgressChanged += BackgroundWorker_ProgressChanged;
- progressDialog = new ProgressDialog(_backgroundWorker);
- }
- public void SetDelagate(MyFunc<string> delegateFunc)
- {
- _delegateFunc = delegateFunc ?? throw new ArgumentNullException(nameof(delegateFunc));
- }
- public void SetProgressBar(ProgressBarStyle pbStyle,string headerText,int mqSpeed)
- {
- progressDialog.PBStyle = pbStyle;
- progressDialog.HeaderText = headerText;
- progressDialog.MQSpeed = mqSpeed;
-
- }
- public void StartQueryExportData(int total, Action<int, string> onCompleted)
- {
-
- if (mainForm == null)
- {
- progressDialog.Show();
- }
- else
- {
- progressDialog.Show(mainForm);
- }
- if (_backgroundWorker.IsBusy) return;
- this._onCompleted = onCompleted;
- _backgroundWorker.RunWorkerAsync(total);
- }
- private Action<int, string> _onCompleted;
- private void BackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
- {
- // 调用传入的方法
- string errMsg = "";
- int result = -1;
- int total = (int)e.Argument; // 获取传入的总项目数
- if (total > 0)
- {
- progressDialog.SetProgress(total);
- //注意,如果_queryExportDataAction 事件里需要更新UI 必须使用 Control.Invoke 或 Control.BeginInvoke。否则会导致程序卡死
- ///类似这样:this.Invoke((MethodInvoker)delegate {labelProgress.Text = $"Progress: {progress}%"; });
- result = _delegateFunc(out errMsg, (progress) =>
- {
- if (!_backgroundWorker.CancellationPending)
- {
- _backgroundWorker.ReportProgress(progress);
- }
- else
- {
- // 如果用户请求了取消,则跳出循环或采取其他措施
- // 这个异常处理查询下
- throw new OperationCanceledException();
- }
- });
- }
- else
- {
- result = _delegateFunc(out errMsg, (progress) => { });
- }
- e.Result = Tuple.Create(result, errMsg);
- }
- private void BackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
- {
- if (!_backgroundWorker.CancellationPending)
- {
- System.Threading.Thread.Sleep(1000);
- }
-
- progressDialog.Close();
- if (e.Error != null)
- {
- // 处理错误
- MessageBox.Show($"An error occurred: {e.Error.Message}");
- }
- else if (e.Cancelled)
- {
- // 处理取消的情况
- MessageBox.Show("Operation was cancelled.");
- }
- else
- {
- var resultTuple = (Tuple<int, string>)e.Result;
- int result = resultTuple.Item1;
- string errMsg = resultTuple.Item2;
- // 调用回调函数,传递结果和错误信息
- _onCompleted?.Invoke(result, errMsg);
- }
- Dispose();
- }
- private void BackgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
- {
- progressDialog.UpdateProgress(e.ProgressPercentage );
- }
- public void Dispose()
- {
- _backgroundWorker.Dispose();
- progressDialog.Dispose();
- }
- }
- }
|