无法将事件附加到自定义任务窗格。 VSTO,Excel 2016

背景

我目前正在使用VSTO2015和Excel 2016中的应用程序。该应用程序在不同的窗口中pipe理多个CustomTaskPanes。 我想获得/ /任务窗格打开或closures时触发// some code 。 为了处理各种窗口,我实现了一个非常类似于这个的结构。

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

ThisAddIn.cs包含以下类;

 public class TaskPaneManager { static Dictionary<string, Microsoft.Office.Tools.CustomTaskPane> _createdPanes = new Dictionary<string, Microsoft.Office.Tools.CustomTaskPane>(); /// <summary> /// Gets the taskpane by name (if exists for current excel window then returns existing instance, otherwise uses taskPaneCreatorFunc to create one). /// </summary> /// <param name="taskPaneId">Some string to identify the taskpane</param> /// <param name="taskPaneTitle">Display title of the taskpane</param> /// <param name="taskPaneCreatorFunc">The function that will construct the taskpane if one does not already exist in the current Excel window.</param> public static Microsoft.Office.Tools.CustomTaskPane GetTaskPane(string taskPaneId, string taskPaneTitle, Func<UserControl> taskPaneCreatorFunc) { string key = string.Format("{0}({1})", taskPaneId, Globals.ThisAddIn.Application.Hwnd); string title = taskPaneId; string windowId = Globals.ThisAddIn.Application.Hwnd.ToString(); if (!_createdPanes.ContainsKey(key)) { var customTaskPane = taskPaneCreatorFunc(); var pane = Globals.ThisAddIn.CustomTaskPanes.Add(customTaskPane, taskPaneTitle); _createdPanes[key] = pane; // // Set the task pane width as set in the App.Config // pane.Width = Convert.ToInt32(ConfigurationManager.AppSettings["TaskPaneWidth"]); } return _createdPanes[key]; } .... 

我从Ribbon.cs调用;

 private void btnUploadWizard_Click(object sender, RibbonControlEventArgs e) { // Check for configuration sheet first. string title = "Upload Wizard"; TaskPaneManager.isConfigurationCreated(); var UploadWizardTaskpane = TaskPaneManager.GetTaskPane(title, title, () => new TaskPaneUploadWizard()); UploadWizardTaskpane.Visible = !UploadWizardTaskpane.Visible; } 

问题:事件处理程序

我很难得到一个事件处理程序来触发。 我不知道我做错了什么。 在TaskPaneDesigner我使用this.VisibleChanged += new System.EventHandler(this.TaskPaneUploadWizard_VisibleChanged);附加事件this.VisibleChanged += new System.EventHandler(this.TaskPaneUploadWizard_VisibleChanged); ,然后在我的TaskPaneUploadWizard类中定义它,如下所示:

 public partial class TaskPaneUploadWizard : UserControl { ... public TaskPaneUploadWizard() { InitializeComponent(); } private void TaskPaneUploadWizard_VisibleChanged(object sender, EventArgs e) { // Some code } 

我的想法

在我看来,好像我要么将事件处理程序附加到CustomTaskPane对象之外,要么在CustomTaskPane创build之前附加它。

帮帮我!

要检测任务窗格是否已打开或closures,您必须附加到paneVisibleChanged事件。

所以最简单的解决scheme是将一行代码添加到GetTaskPane方法中:

 var pane = Globals.ThisAddIn.CustomTaskPanes.Add(customTaskPane, taskPaneTitle); // This is the new line to be added. pane.VisibleChanged += (s, e) => customTaskPane.Visible = pane.Visible; _createdPanes[key] = pane; 

现在整个任务窗格的可见性将被传递到它的内容,并且/或者应该执行// some code

或者,如果您不想由于某种原因手动设置customTaskPane.Visible ,则可以直接在这个新的事件处理程序中执行代码:

 pane.VisibleChanged += (s, e) => { /* some code */ }; 

但个人而言,我宁愿推荐第一种方法,因为它似乎更适合您现有的代码。

 var UploadWizardTaskpane = TaskPaneManager.GetTaskPane(title, title, () => new TaskPaneUploadWizard()); 

这是创build一个CustomTaskPane而不是一个TaskPaneUploadWizard对象

看起来像这样this.VisibleChanged += new System.EventHandler(this.TaskPaneUploadWizard_VisibleChanged); 正在TaskPaneUploadWizardTaskPaneUploadWizard ,它只是CustomTaskPane的访客

请注意, CustomTaskPane的可见性不会影响TaskPaneUploadWizard

我的build议

您从devise器中删除VisibleChanged ,您将在TaskPaneUploadWizard手动添加它

 public partial class TaskPaneUploadWizard : UserControl { //{---} CustomTaskPane _HostPane; public CustomTaskPane HostPane { get => _HostPane; set { if(_HostPane == value) return; _HostPane?.VisibleChanged -= TaskPaneUploadWizard_VisibleChanged; _HostPane = value; _HostPane?.VisibleChanged += TaskPaneUploadWizard_VisibleChanged; } } //{---} private void TaskPaneUploadWizard_VisibleChanged(object sender, EventArgs e) { // Some code } //{---} 

然后在GetTaskPane

 //{---} var pane = Globals.ThisAddIn.CustomTaskPanes.Add(customTaskPane, taskPaneTitle); (customTaskPane as TaskPaneUploadWizard).HostPane = pane; //{---}