123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782 |
- using PTMedicalInsurance.Variables;
- using System;
- using System.Collections.Generic;
- using System.ComponentModel;
- using System.Drawing;
- 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}";
- // //}
- // if (this.IsHandleCreated)
- // {
- // 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();
- // /// <summary>
- // /// 接收一个动态可变的入参,各种参数均可接收;回调函数返回总条数和当前进度
- // /// </summary>
- // /// <typeparam name="T1"></typeparam>
- // /// <param name="o"></param>
- // /// <param name="err"></param>
- // /// <param name="progressCallback"></param>
- // /// <param name="progressMaxCallback"></param>
- // /// <returns></returns>
- // public delegate int MyFunc<T1>(object[] o,out T1 err,ProgressCallback progressCallback,ProgressMaxCallback progressMaxCallback);
- // private MyFunc<string> _delegateFunc;
- // private ProgressDialog progressDialog ;
- // private Form mainForm;
- // private object[] _o;
- // // 定义进度回调委托
- // //返回当前进度
- // public delegate void ProgressCallback(int progress);
- // //返回进度条总条数
- // public delegate void ProgressMaxCallback(int max);
- // public DataLoader(MyFunc<string> delegateFunc, Form frm)
- // {
- // mainForm = frm;
- // _delegateFunc = delegateFunc ?? throw new ArgumentNullException(nameof(delegateFunc));
- // }
- // 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 Start(int total, Action<int, string> onCompleted)
- // {
- // // 配置 BackgroundWorker
- // _backgroundWorker.WorkerReportsProgress = true;
- // _backgroundWorker.WorkerSupportsCancellation = true;
- // _backgroundWorker.DoWork += BackgroundWorker_DoWork;
- // _backgroundWorker.RunWorkerCompleted += BackgroundWorker_RunWorkerCompleted;
- // _backgroundWorker.ProgressChanged += BackgroundWorker_ProgressChanged;
- // progressDialog = new ProgressDialog(_backgroundWorker);
- // if (mainForm == null)
- // {
- // progressDialog.Show();
- // }
- // else
- // {
- // progressDialog.Show(mainForm);
- // }
- // if (_backgroundWorker.IsBusy) return;
- // this._onCompleted = onCompleted;
- // _backgroundWorker.RunWorkerAsync(total);
- // }
- // public void Start(Action<int, string> onCompleted)
- // {
- // // 配置 BackgroundWorker
- // _backgroundWorker.WorkerReportsProgress = true;
- // _backgroundWorker.WorkerSupportsCancellation = true;
- // _backgroundWorker.DoWork += BackgroundWorker_DoWork;
- // _backgroundWorker.RunWorkerCompleted += BackgroundWorker_RunWorkerCompleted;
- // _backgroundWorker.ProgressChanged += BackgroundWorker_ProgressChanged;
- // progressDialog = new ProgressDialog(_backgroundWorker);
- // if (mainForm == null)
- // {
- // progressDialog.Show();
- // }
- // else
- // {
- // progressDialog.Show(mainForm);
- // }
- // if (_backgroundWorker.IsBusy) return;
- // this._onCompleted = onCompleted;
- // _backgroundWorker.RunWorkerAsync();
- // }
- // public void Start(object[] o,Action<int, string> onCompleted)
- // {
- // // 配置 BackgroundWorker
- // _backgroundWorker.WorkerReportsProgress = true;
- // _backgroundWorker.WorkerSupportsCancellation = true;
- // _backgroundWorker.DoWork += BackgroundWorker_DoWorkO;
- // _backgroundWorker.RunWorkerCompleted += BackgroundWorker_RunWorkerCompleted;
- // _backgroundWorker.ProgressChanged += BackgroundWorker_ProgressChanged;
- // progressDialog = new ProgressDialog(_backgroundWorker);
- // if (mainForm == null)
- // {
- // progressDialog.Show();
- // }
- // else
- // {
- // progressDialog.Show(mainForm);
- // }
- // if (_backgroundWorker.IsBusy) return;
- // this._onCompleted = onCompleted;
- // _backgroundWorker.RunWorkerAsync();
- // }
- // private Action<int, string> _onCompleted;
- // private void BackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
- // {
- // // 调用传入的方法
- // string errMsg = "";
- // int result = -1;
- // //注意,如果_queryExportDataAction 事件里需要更新UI 必须使用 Control.Invoke 或 Control.BeginInvoke。否则会导致程序卡死
- // ///类似这样:this.Invoke((MethodInvoker)delegate {labelProgress.Text = $"Progress: {progress}%"; });
- // result = _delegateFunc(null, out errMsg, (progress) =>
- // {
- // if (!_backgroundWorker.CancellationPending)
- // {
- // _backgroundWorker.ReportProgress(progress);
- // }
- // else
- // {
- // // 如果用户请求了取消,则跳出循环或采取其他措施
- // // 这个异常处理查询下
- // throw new OperationCanceledException();
- // }
- // },
- // (max) =>
- // {
- // if (!_backgroundWorker.CancellationPending)
- // {
- // progressDialog.SetProgress(max); ;
- // }
- // else
- // {
- // // 如果用户请求了取消,则跳出循环或采取其他措施
- // // 这个异常处理查询下
- // throw new OperationCanceledException();
- // }
- // }
- // );
- // e.Result = Tuple.Create(result, errMsg);
- // }
- // private void BackgroundWorker_DoWorkO(object sender, DoWorkEventArgs e)
- // {
- // // 调用传入的方法
- // string errMsg = "";
- // int result = -1;
- // //注意,如果_queryExportDataAction 事件里需要更新UI 必须使用 Control.Invoke 或 Control.BeginInvoke。否则会导致程序卡死
- // ///类似这样:this.Invoke((MethodInvoker)delegate {labelProgress.Text = $"Progress: {progress}%"; });
- // result = _delegateFunc(_o, out errMsg, (progress) =>
- // {
- // if (!_backgroundWorker.CancellationPending)
- // {
- // _backgroundWorker.ReportProgress(progress);
- // }
- // else
- // {
- // // 如果用户请求了取消,则跳出循环或采取其他措施
- // // 这个异常处理查询下
- // throw new OperationCanceledException();
- // }
- // },
- // (max) =>
- // {
- // if (!_backgroundWorker.CancellationPending)
- // {
- // progressDialog.SetProgress(max); ;
- // }
- // else
- // {
- // // 如果用户请求了取消,则跳出循环或采取其他措施
- // // 这个异常处理查询下
- // throw new OperationCanceledException();
- // }
- // }
- // );
- // 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();
- // }
- //}
- public class ProgressDialog : Form
- {
- private ProgressBar _progressBar;
- private Label _labelStatus;
- private Button _cancelButton;
- private BackgroundWorker _backgroundWorker;
- private int _maximum = 100;
- private string _header = "正在查询...";
- public string HeaderText
- {
- get => _header;
- set { Text = _header = value; }
- }
- public ProgressBarStyle PBStyle
- {
- get => _progressBar.Style;
- set => _progressBar.Style = value;
- }
- public int MQSpeed
- {
- get => _progressBar.MarqueeAnimationSpeed;
- set => _progressBar.MarqueeAnimationSpeed = value;
- }
- public ProgressDialog()
- {
- InitializeComponent();
- }
- public ProgressDialog(BackgroundWorker backgroundWorker) : this()
- {
- _backgroundWorker = backgroundWorker;
- }
- private void InitializeComponent()
- {
- Application.EnableVisualStyles();
- // 设置窗体样式
- Text = _header;
- StartPosition = FormStartPosition.CenterParent;
- FormBorderStyle = FormBorderStyle.FixedDialog;
- MaximizeBox = false;
- MinimizeBox = false;
- ShowInTaskbar = false;
- TopMost = true;
- ClientSize = new Size(284, 100);
- CenterToScreen();
- // 初始化进度条
- _progressBar = new ProgressBar
- {
- Location = new Point(12, 12),
- Size = new Size(260, 23),
- Style = ProgressBarStyle.Marquee,
- MarqueeAnimationSpeed = 50
- };
- Controls.Add(_progressBar);
- // 状态标签
- _labelStatus = new Label
- {
- Location = new Point(12, 41),
- Size = new Size(260, 23)
- };
- Controls.Add(_labelStatus);
- // 取消按钮
- _cancelButton = new Button
- {
- Text = "取消",
- Location = new Point(197, 60),
- Size = new Size(75, 23)
- };
- _cancelButton.Click += CancelButton_Click;
- Controls.Add(_cancelButton);
- SetStyle(ControlStyles.ResizeRedraw, true);
- }
- public int ProgressValue
- {
- set
- {
- if (this.IsHandleCreated)
- {
- this.InvokeIfRequired(() =>
- {
- _progressBar.Value = value;
- _labelStatus.Text = $"已完成 {value}/{_maximum}";
- if (value == _maximum || value >= _progressBar.Maximum)
- {
- _progressBar.Refresh();
- _labelStatus.Refresh();
- }
- });
- }
- }
- }
- public void SetProgress(int max)
- {
- _maximum = max;
- _progressBar.Maximum = max;
- }
- public string StatusText
- {
- set => this.InvokeIfRequired(() => _labelStatus.Text = value);
- }
- private void CancelButton_Click(object sender, EventArgs e)
- {
- if (_backgroundWorker != null && _backgroundWorker.WorkerSupportsCancellation)
- {
- _backgroundWorker.CancelAsync();
- }
- this.Close();
- }
- public async void ShowAsync()
- {
- await Task.Run(() =>
- {
- Application.Run(this);
- });
- }
- protected override void OnClosed(EventArgs e)
- {
- base.OnClosed(e);
- _backgroundWorker = null;
- }
- }
- // 扩展方法:简化 Invoke 操作
- public static class ControlExtensions
- {
- public static void InvokeIfRequired(this Control control, MethodInvoker action)
- {
- if (control.InvokeRequired)
- {
- try
- {
- control.Invoke(action);
- }
- catch (Exception ex) when (ex is InvalidOperationException || ex is InvalidAsynchronousStateException)
- {
- // 忽略无效句柄操作
- Console.WriteLine("无法执行 Invoke:" + ex.Message);
- }
- }
- else
- {
- action();
- }
- }
- }
- public class DataLoader : IDisposable
- {
- private readonly BackgroundWorker _backgroundWorker;
- private ProgressDialog _progressDialog;
- private readonly Form _ownerForm;
- private readonly MyFunc<string> _delegateFunc;
- private Action<int, string> _onCompleted;
- private bool _disposed = false;
- public delegate int MyFunc<T>(object[] o, out T err, ProgressCallback progressCallback, ProgressMaxCallback progressMaxCallback, BackgroundWorker worker);
- public delegate void ProgressCallback(int progress);
- public delegate void ProgressMaxCallback(int max);
- public DataLoader(MyFunc<string> func, Form ownerForm)
- {
- _delegateFunc = func ?? throw new ArgumentNullException(nameof(func));
- _ownerForm = ownerForm;
- _backgroundWorker = new BackgroundWorker
- {
- WorkerReportsProgress = true,
- WorkerSupportsCancellation = true
- };
- _backgroundWorker.DoWork += BackgroundWorker_DoWork;
- _backgroundWorker.ProgressChanged += BackgroundWorker_ProgressChanged;
- _backgroundWorker.RunWorkerCompleted += BackgroundWorker_RunWorkerCompleted;
- }
- public void SetProgressBar(ProgressBarStyle style, string headerText, int mqSpeed)
- {
- if (_progressDialog == null || _progressDialog.IsDisposed)
- {
- _progressDialog = new ProgressDialog(_backgroundWorker)
- {
- PBStyle = style,
- HeaderText = headerText,
- MQSpeed = mqSpeed
- };
- }
- }
- public void Start(object[] args, Action<int, string> onCompleted)
- {
- if (_backgroundWorker.IsBusy) return;
- _onCompleted = onCompleted;
- if (_ownerForm == null || _ownerForm.IsDisposed)
- {
- _progressDialog?.Show();
- }
- else
- {
- _progressDialog?.Show(_ownerForm);
- }
- _backgroundWorker.RunWorkerAsync(args);
- }
- private void BackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
- {
- //var args = (object[])e.Argument;
- //string errMsg = "";
- //int result = -1;
- //try
- //{
- // result = _delegateFunc(args, out errMsg,
- // progress => _backgroundWorker.ReportProgress(progress),
- // max => _progressDialog?.SetProgress(max));
- //}
- //catch (Exception ex)
- //{
- // errMsg = ex.Message;
- // result = 0;
- //}
- //e.Result = Tuple.Create(result, errMsg);
- var worker = sender as BackgroundWorker;
- if (worker == null)
- {
- e.Result = Tuple.Create(-1, "BackgroundWorker 实例无效");
- return;
- }
- var args = e.Argument as object[];
- if (args == null || args.Length == 0)
- {
- e.Result = Tuple.Create(-1, "参数无效");
- return;
- }
- string errMsg = "";
- int result = -1;
- try
- {
- // 定义进度报告的 Action
- ProgressCallback progressAction = percent =>
- {
- if (worker.WorkerReportsProgress && !worker.CancellationPending)
- worker.ReportProgress(percent);
- };
- // 定义设置最大值的 Action
- ProgressMaxCallback setProgressAction = max =>
- {
- if (_progressDialog != null && !_progressDialog.IsDisposed)
- _progressDialog.SetProgress(max);
- };
- // 调用实际业务逻辑
- result = _delegateFunc(args, out errMsg, progressAction, setProgressAction,_backgroundWorker);
- }
- catch (Exception ex)
- {
- errMsg = $"后台任务发生异常: {ex.Message}";
- result = 0;
- }
- // 返回结果给 RunWorkerCompleted 事件
- e.Result = Tuple.Create(result, errMsg);
- }
- private void BackgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
- {
- //_progressDialog?.UpdateProgress(e.ProgressPercentage);
- _progressDialog.ProgressValue = (e.ProgressPercentage);
- }
- private void BackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
- {
- if (e.Cancelled)
- {
- MessageBox.Show("操作已取消");
- }
- else if (e.Error != null)
- {
- MessageBox.Show($"发生错误:{e.Error.Message}");
- }
- else
- {
- var resultTuple = (Tuple<int, string>)e.Result;
- _onCompleted?.Invoke(resultTuple.Item1, resultTuple.Item2);
- }
- _progressDialog?.Close();
- _progressDialog?.Dispose();
- _progressDialog = null;
- }
- #region IDisposable Support
- protected virtual void Dispose(bool disposing)
- {
- if (!_disposed)
- {
- if (disposing)
- {
- _backgroundWorker.Dispose();
- _progressDialog?.Dispose();
- }
- _disposed = true;
- }
- }
- public void Dispose()
- {
- Dispose(true);
- GC.SuppressFinalize(this);
- }
- #endregion
- }
- }
|