VSTO(C#)Excel开发11:自定义任务窗格与多个工作簿

初级代码游戏的专栏介绍与文章目录-CSDN博客

我的github:codetoys,所有代码都将会位于ctfc库中。已经放入库中我会指出在库中的位置。

这些代码大部分以Linux为目标但部分代码是纯C++的,可以在任何平台上使用。

源码指引:github源码指引_初级代码游戏的博客-CSDN博客


上一篇VSTO(C#)Excel开发10:启动和卸载顺序 事件处理-CSDN博客

基本的技术我们已经弄得七七八八了,但是当我们在同时打开多个工作簿的时候发现出大问题了:任务窗格只能出现在第一次打开工作簿上,我们在其他工作簿上操作,内容仍然输出到第一个工作簿的任务窗格上。

这是怎么回事呢?

目录

一、任务窗格创建在哪里

二、管理多个工作簿的任务窗格

三、效果


一、任务窗格创建在哪里

回头看一下我们之前是如何创建任务窗格的(VSTO(C#)Excel开发7:自定义任务窗格-CSDN博客):

cs 复制代码
		private void ThisAddIn_Startup(object sender, System.EventArgs e)
        {
			userControl1 = new UserControl1();
			myPane = this.CustomTaskPanes.Add(userControl1, "userControl1");
			myPane.Visible = true;

我们只有唯一的窗体控件,自然只能出现在一个窗体上,这是可以理解的。但是CustomTaskPanes.Add也没说添加到哪里去了啊,这是怎么回事呢?

原来这个CustomTaskPanes.Add是很鬼的,它自动把任务窗格添加到当前的工作簿上去了。

所以我们需一个复杂的机制来管理多个工作簿的任务窗格,将工作簿对象和任务窗格关联起来。

二、管理多个工作簿的任务窗格

我们需要一个类来管理:

cs 复制代码
using Microsoft.Office.Interop.Excel;
using Microsoft.Office.Tools;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web.UI;

namespace ctExcelTools
{
	//管理自定义任务窗格(面板),注意CustomTaskPanes.Add会在当前活动工作簿上创建任务窗格
	public class PanelMgr
	{
		private Dictionary<Workbook, (CustomTaskPane, UserControlFitToOnePage)> m_Panels = new Dictionary<Workbook, (CustomTaskPane, UserControlFitToOnePage)>();
		public (CustomTaskPane, UserControlFitToOnePage) GetPanel(Workbook workbook)
		{
			if (!m_Panels.ContainsKey(workbook))
			{
				UserControlFitToOnePage userControlFitToOnePage = new UserControlFitToOnePage();
				CustomTaskPane panel = Globals.ThisAddIn.CustomTaskPanes.Add(userControlFitToOnePage, workbook.Name);
				m_Panels.Add(workbook, (panel, userControlFitToOnePage));
			}
			return m_Panels[workbook];
		}
		public void Remove(Workbook workbook)
		{
			m_Panels.Remove(workbook);
		}
	}
}

这个类的原理就是如果工作簿还没有任务窗格就创建,否则就返回已经存在的。创建的时候用的是工作簿的名字,方便确认功能符合我们的预期,实际使用的时候还是应该用相同的名称。

在主类里定义一个PanelMgr:

cs 复制代码
	public partial class ThisAddIn
	{
		public PanelMgr panelMgr = new PanelMgr();

在必要的时候创建:

cs 复制代码
			(CustomTaskPane, UserControlFitToOnePage) tmp = Globals.ThisAddIn.panelMgr.GetPanel(workbook);
			tmp.Item1.Visible = true;
			tmp.Item2.textBox_Info.Text += DateTime.Now.ToString() + "\r\n";

根据我们前面PanelMge的定义,返回的群组对象的Item1是任务窗格,Item2是窗体控件。

当然我们也需要在工作簿关闭的时候删除掉PanelMgr里的信息:

cs 复制代码
			this.Application.WorkbookBeforeClose += Application_WorkbookBeforeClose;

		private void Application_WorkbookBeforeClose(Microsoft.Office.Interop.Excel.Workbook workbook, ref bool Cancel)
		{
			//MessageBox.Show("Application_WorkbookBeforeClose");
			panelMgr.Remove(workbook);
		}

忘了删除好像问题也不大?

三、效果

执行程序,打开两个工作簿:

这样问题就解决了。


下一篇 VSTO(C#)Excel开发12:多线程的诡异-CSDN博客


(这里是文档结束)

相关推荐
张人玉4 小时前
C# 通讯关键类的API
开发语言·c#
芭拉拉小魔仙4 小时前
Vue项目中如何实现表格选中数据的 Excel 导出
前端·vue.js·excel
RE-19014 小时前
Excel基础知识 - 导图笔记
数据分析·学习笔记·excel·思维导图·基础知识·函数应用
Love__Tay9 小时前
【数据分析与可视化】2025年一季度金融业主要行业资产、负债、权益结构与增速对比
金融·excel·pandas·matplotlib
泉城老铁11 小时前
导出大量数据时如何优化内存使用?SXSSFWorkbook的具体实现方法是什么?
spring boot·后端·excel
William_cl12 小时前
C# MVC 修复DataTable时间排序以及中英文系统的时间筛选问题
开发语言·c#·mvc
c#上位机13 小时前
wpf之RelativeSource用法总结
c#·wpf
Dm_dotnet13 小时前
WPF应用最小化到系统托盘
c#
*长铗归来*15 小时前
ASP.NET Core Web API 中控制器操作的返回类型及Swagger
后端·c#·asp.net·.netcore
Damon小智15 小时前
玩转ClaudeCode:通过Excel-MCP实现数据清洗并写入Excel
ai·excel·ai编程·claude·chrome devtools·rpa·claude code