using Org.BouncyCastle.Asn1.Crmf; using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Text; using System.Threading.Tasks; using static System.Net.Mime.MediaTypeNames; using System.Windows.Forms; using System.Drawing; namespace PTMedicalInsurance.Helper { [DesignerCategory("Code")] 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() { InitComponent(); } public ProgressDialog(BackgroundWorker backgroundWorker) : this() { _backgroundWorker = backgroundWorker; } public void InitComponent() { System.Windows.Forms.Application.EnableVisualStyles(); // 设置窗体样式 Text = _header; StartPosition = FormStartPosition.CenterParent; FormBorderStyle = FormBorderStyle.FixedDialog; MaximizeBox = false; MinimizeBox = false; ShowInTaskbar = false; TopMost = true; ClientSize = new Size(800, 100); CenterToScreen(); // 初始化进度条 _progressBar = new ProgressBar { Location = new Point(12, 12), Size = new Size(700, 23), Style = ProgressBarStyle.Marquee, MarqueeAnimationSpeed = 50 }; Controls.Add(_progressBar); // 状态标签 _labelStatus = new Label { Location = new Point(12, 41), Size = new Size(360, 23) }; Controls.Add(_labelStatus); // 取消按钮 _cancelButton = new Button { Text = "取消", Location = new Point(520, 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(() => { System.Windows.Forms.Application.Run(this); }); } protected override void OnClosed(EventArgs e) { base.OnClosed(e); _backgroundWorker = null; } } 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 DataLoaderContext { // public object[] args { get; set; } //入参 // 回调函数(替代委托参数) public delegate void ProgressCallback(int progress); public delegate void ProgressMaxCallback(int max); public ProgressCallback reportProgress { get; set; } public delegate void SetProgressMaximum(int max); // 最大值 public ProgressMaxCallback setProgressMaximum { get; set; } public delegate void SetProgressHeaderText(ProgressBarStyle progressBarStyle, string content, int speed); public SetProgressHeaderText setProgressHeaderText { get; set; } public Action OnCompleted { get; set; } // 完成回调(可选) // 取消支持 public BackgroundWorker Worker { get; set; } // 用于取消检查 } class ProgressWrapper { private readonly BackgroundWorker _backgroundWorker; private ProgressDialog _progressDialog; private readonly Form _ownerForm; public delegate int MyFunc(DataLoaderContext context, out T err); private readonly MyFunc _delegateFunc; private Action _onCompleted; private bool _disposed = false; public delegate void ProgressCallback(int progress); public delegate void ProgressMaxCallback(int max); public ProgressWrapper(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 }; } else { if (mqSpeed < 0) mqSpeed = 50; _progressDialog.PBStyle = style; _progressDialog.HeaderText = headerText; _progressDialog.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 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 { DataLoaderContext context = new DataLoaderContext(); context.Worker = _backgroundWorker; context.args = _args; // 定义进度报告的 Action DataLoaderContext.ProgressCallback _reportProgress = percent => { if (worker.WorkerReportsProgress && !worker.CancellationPending) worker.ReportProgress(percent); }; // 定义设置最大值的 Action DataLoaderContext.ProgressMaxCallback _setProgressMax = max => { if (_progressDialog != null && !_progressDialog.IsDisposed) _progressDialog.SetProgress(max); }; // 设置标题 DataLoaderContext.SetProgressHeaderText _setProgressHeader = (progressBarStyle, header, speed) => { if (_progressDialog != null && !_progressDialog.IsDisposed) SetProgressBar(progressBarStyle, header, speed); }; context.reportProgress = _reportProgress; context.setProgressMaximum = _setProgressMax; context.setProgressHeaderText = _setProgressHeader; context.Worker = _backgroundWorker; // 调用实际业务逻辑 result = _delegateFunc(context, out errMsg); } 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 } }