using MainShell.Resources.CustomControl; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; namespace MainShell.Common { public static class Loading { private static LoadingWaitView _view; // 全局初始化:在主程序启动或插件加载时调用一次 public static void Initialize(Window mainWindow) { if (_view != null) return; // 避免重复加载 _view = new LoadingWaitView(); // 获取窗口的根内容 var rootContent = mainWindow.Content; if (rootContent is Panel rootPanel) { // 如果根部本来就是 Panel (Grid/Canvas等),直接添加 rootPanel.Children.Add(_view); } else if (rootContent is ContentControl contentControl) { // 如果根部是 ContentControl,我们需要把原本的内容包在一个新的 Grid 里 var originalContent = contentControl.Content as UIElement; contentControl.Content = null; var wrapperGrid = new Grid(); wrapperGrid.Children.Add(originalContent); // 原有内容 wrapperGrid.Children.Add(_view); // 我们的遮罩层 contentControl.Content = wrapperGrid; } // 确保遮罩层铺满并置于顶层 Grid.SetColumnSpan(_view, 99); Grid.SetRowSpan(_view, 99); Panel.SetZIndex(_view, 9999); } // 基础调用:Loading.Show("计算中..."); public static void Show(string msg, bool isIndeterminate, bool canCancel = true) => LoadingService.Instance.Show(msg, canCancel, isIndeterminate); public static void Hide() => LoadingService.Instance.Hide(); public static void Report(double val) => LoadingService.Instance.Report(val); // 获取当前令牌:Loading.Token public static CancellationToken Token => LoadingService.Instance.Token; // 高级用法:使用 using 块自动开启和关闭 public static IDisposable Manager(string msg, bool canCancel = true) { Show(msg, canCancel); return new DisposableAction(() => Hide()); } public static async Task RunAsync( Func, Task> work, string message, bool canCancel = true, bool isIndeterminate = false, Action onError = null) { using (Manager(message, canCancel)) { try { LoadingService.Instance.Show(message, isIndeterminate, canCancel); var progress = new Progress(val => Application.Current.Dispatcher.Invoke(() => LoadingService.Instance.ProgressValue = val)); await Task.Run(() => work(LoadingService.Instance.Token, progress), LoadingService.Instance.Token); return true; // 执行成功 } catch (OperationCanceledException) { // 用户点击了取消,通常不需要弹窗,直接返回 false return false; } catch (Exception ex) { // 捕获其他所有异常(硬件错误、逻辑错误等) if (onError != null) onError(ex); else MessageBox.Show($"操作失败: {ex.Message}", "系统错误", MessageBoxButton.OK, MessageBoxImage.Error); return false; } } } } }