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(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(); // /// // /// 接收一个动态可变的入参,各种参数均可接收;回调函数返回总条数和当前进度 // /// // /// // /// // /// // /// // /// // /// // public delegate int MyFunc(object[] o,out T1 err,ProgressCallback progressCallback,ProgressMaxCallback progressMaxCallback); // private MyFunc _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 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 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 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 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 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 _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)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 _delegateFunc; private Action _onCompleted; private bool _disposed = false; public delegate int MyFunc(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 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 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)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 } }