using System; using System.Threading; using System.Windows; using System.Windows.Controls; using System.Windows.Threading; namespace Laservall.Solidworks.Windows { /// /// A progress dialog built entirely in code to avoid cross-thread XAML /// parsing issues when shown on a dedicated STA thread (the WPF Application /// instance lives on the main SolidWorks thread). /// public class ResolvingProgressWindow : Window { private readonly ManualResetEventSlim _rendered = new ManualResetEventSlim(false); private ResolvingProgressWindow() { Title = "正在处理"; Width = 360; Height = 140; WindowStartupLocation = WindowStartupLocation.CenterScreen; WindowStyle = WindowStyle.ToolWindow; ResizeMode = ResizeMode.NoResize; Topmost = true; ShowInTaskbar = false; var label = new TextBlock { Text = "正在反轻化,请稍候...", FontSize = 14, HorizontalAlignment = HorizontalAlignment.Center, Margin = new Thickness(0, 0, 0, 16) }; var progressBar = new ProgressBar { Height = 20, IsIndeterminate = true }; var stack = new StackPanel { VerticalAlignment = VerticalAlignment.Center }; stack.Children.Add(label); stack.Children.Add(progressBar); var grid = new Grid { Margin = new Thickness(20) }; grid.Children.Add(stack); Content = grid; ContentRendered += (s, e) => _rendered.Set(); } public static void RunWithProgress(Action action) { if (action == null) throw new ArgumentNullException(nameof(action)); Dispatcher windowDispatcher = null; ManualResetEventSlim rendered = null; var ready = new ManualResetEventSlim(false); var uiThread = new Thread(() => { try { var window = new ResolvingProgressWindow(); rendered = window._rendered; windowDispatcher = window.Dispatcher; ready.Set(); window.Show(); Dispatcher.Run(); } catch { ready.Set(); } }); uiThread.SetApartmentState(ApartmentState.STA); uiThread.IsBackground = true; uiThread.Name = "ResolvingProgressUI"; uiThread.Start(); ready.Wait(); // Wait for the window to fully render before starting the blocking action if (rendered != null) { rendered.Wait(3000); } try { action(); } finally { if (windowDispatcher != null) { windowDispatcher.InvokeShutdown(); } } } } }