无法将事件附加到自定义任务窗格。 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,您必须附加到pane
的VisibleChanged
事件。
所以最简单的解决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);
正在TaskPaneUploadWizard
上TaskPaneUploadWizard
,它只是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; //{---}