如何为Excel VSTO加载项添加显示进度的启动屏?
Excel VSTO加载项启动屏实现示例
步骤1:创建启动屏窗体
在你的VSTO项目中添加一个Windows Forms窗体(命名为SplashScreenForm),做如下设置:
- 添加
Label控件(命名lblProgress,用于显示阶段文本) - 添加
ProgressBar控件(命名progressBar1,展示进度) - 设置窗体样式:
FormBorderStyle改为None,StartPosition设为CenterScreen,可按需添加Logo或调整配色
窗体代码如下:
using System.Windows.Forms; namespace YourVSTOAddInNamespace { public partial class SplashScreenForm : Form { public SplashScreenForm() { InitializeComponent(); } // 跨线程安全的进度更新方法 public void UpdateProgress(string statusText, int progressValue) { if (lblProgress.InvokeRequired) { lblProgress.Invoke(new MethodInvoker(() => { lblProgress.Text = statusText; progressBar1.Value = progressValue; })); } else { lblProgress.Text = statusText; progressBar1.Value = progressValue; } } } }
步骤2:在加载项中调用启动屏
修改ThisAddIn.cs的启动事件,用后台线程执行初始化任务,同时更新启动屏:
using System; using System.Threading.Tasks; using System.Windows.Forms; namespace YourVSTOAddInNamespace { public partial class ThisAddIn { private SplashScreenForm _splashScreen; private void ThisAddIn_Startup(object sender, EventArgs e) { // 显示启动屏 _splashScreen = new SplashScreenForm(); _splashScreen.Show(); // 后台执行初始化流程 Task.Run(async () => { try { // 阶段1:加载配置文件 _splashScreen.UpdateProgress("加载配置中...", 20); await Task.Delay(1000); // 替换为实际耗时操作 // 阶段2:初始化业务数据 _splashScreen.UpdateProgress("初始化数据中...", 50); await Task.Delay(1000); // 阶段3:完成加载 _splashScreen.UpdateProgress("加载完成!", 100); await Task.Delay(500); } finally { // 安全关闭启动屏 if (_splashScreen.InvokeRequired) { _splashScreen.Invoke(new MethodInvoker(() => _splashScreen.Close())); } else { _splashScreen.Close(); } _splashScreen.Dispose(); } }); } private void ThisAddIn_Shutdown(object sender, EventArgs e) { // 清理资源 if (_splashScreen != null && !_splashScreen.IsDisposed) { _splashScreen.Close(); _splashScreen.Dispose(); } } #region VSTO生成代码 private void InternalStartup() { this.Startup += ThisAddIn_Startup; this.Shutdown += ThisAddIn_Shutdown; } #endregion } }
关键注意事项
- 必须添加
System.Windows.Forms引用到VSTO项目中 - 所有更新UI的操作必须用
Invoke,避免跨线程异常 - 如果初始化过程需要操作Excel对象(比如读取工作表),必须回到主线程执行:
this.Application.Invoke(new MethodInvoker(() => { // 这里写Excel相关操作代码 var activeSheet = this.Application.ActiveWorkbook.ActiveSheet; }));
内容的提问来源于stack exchange,提问作者CGarden
相关产品推荐
相关产品推荐

