Excel中的CustomTaskPane不会出现在新工作簿中

我在Excel 2013中添加了一个CustomTaskPane,可以让用户快速搜索照片。 如果用户只打开/创建一个工作簿,它的工作正常。 问题是,如果他们打开另一个工作簿或创建一个新工作簿,任务窗格不会出现在出现的新窗口中。 它只是放在原来的窗口。 我知道这种行为是由于我只是在打开Excel时初始化面板而引起的。 我向ActiveWindow事件添加了一个事件处理程序,以便在打开另一个工作簿时初始化一个新面板。

问题是我无法弄清楚如何判断CustomTaskPane是否已经存在于窗口中。 如果是,则简单地创建另一个CustomTaskPane,因此在该窗口中现在有两个。 我编写了以下代码来处理原始文件并创建一个新文件,但它引入了一些滞后(1-5秒),每次更改工作簿窗口时都会引起用户疯狂。 有没有办法查看窗口中是否已存在CustomTaskPane以避免处置和重新创建新的以避免堆叠重复的任务窗格?

Microsoft.Office.Tools.CustomTaskPane PartPhotoTaskPane; Globals.ThisAddIn.Application.WindowActivate += Application_WindowActivate; void Application_WindowActivate(Excel.Workbook Wb, Excel.Window Wn) { if (PartPhotoTaskPane != null) { PartPhotoTaskPane.Dispose(); InitalizePartPhotoViewerTaskPane(EPPF); } else { InitalizePartPhotoViewerTaskPane(EPPF); } } ///  /// Start up the part photo viewer task pane ///  private void InitalizePartPhotoViewerTaskPane(ExcelPartPhotoFunctions _EPPF) { //intialize the part search try { PartPhotoTaskPane = Globals.ThisAddIn.CustomTaskPanes.Add(new PartPhotoSearchPane(_EPPF), "Part Information", Globals.ThisAddIn.Application.ActiveWindow); PartPhotoTaskPane.Visible = Properties.Settings.Default.InfoPaneOpenStatus; PartPhotoTaskPane.Width = 260; } catch (Exception e) { MessageBox.Show("Error starting Part Info Toolbar:" + Environment.NewLine + e.Message + Environment.NewLine + e.StackTrace, "Error!", MessageBoxButtons.OK, MessageBoxIcon.Error); } } 

使用hwnd(Globals.ThisAddIn.Application.Hwnd)标识Excel窗口。 这对于Office2013(使用SDI方法)和使用MDI窗口的旧版Office都很有效。 这是一个可以用于此的类:

 public class TaskPaneManager { static Dictionary _createdPanes = new Dictionary(); ///  /// Gets the taskpane by name (if exists for current excel window then returns existing instance, otherwise uses taskPaneCreatorFunc to create one). ///  /// Some string to identify the taskpane /// Display title of the taskpane /// The function that will construct the taskpane if one does not already exist in the current Excel window. public static CustomTaskPane GetTaskPane(string taskPaneId, string taskPaneTitle, Func taskPaneCreatorFunc) { string key = string.Format("{0}({1})", taskPaneId, Globals.ThisAddIn.Application.Hwnd); if (!_createdPanes.ContainsKey(key)) { var pane = Globals.ThisAddIn.CustomTaskPanes.Add(taskPaneCreatorFunc(), taskPaneTitle); _createdPanes[key] = pane; } return _createdPanes[key]; } } 

在这里,我实际上将Excel窗口hwnd和一些任意字符串标识符组合在一起以识别任务窗格。 这个想法是在同一个插件中支持多个任务窗格。

以下是如何从function区中使用它的示例:

  private void button1_Click(object sender, RibbonControlEventArgs e) { var taskpane = TaskPaneManager.GetTaskPane("A", "Task pane type A", () => new UserControl1()); taskpane.Visible = !taskpane.Visible; } private void button2_Click(object sender, RibbonControlEventArgs e) { var taskpane = TaskPaneManager.GetTaskPane("B", "Task pane type B", () => new UserControl2()); taskpane.Visible = !taskpane.Visible; } 

如果在Excel中打开多个工作簿,则两个Excel窗口都将具有自己的taspaneA和taskpaneB。