C# 将事件附加到自定义任务窗格时出现问题。VSTO,Excel 2016 背景

C# 将事件附加到自定义任务窗格时出现问题。VSTO,Excel 2016 背景,c#,excel,vsto,C#,Excel,Vsto,我目前正在VSTO2015和Excel 2016中开发一个应用程序。该应用程序在不同的窗口中管理多个CustomTaskPane。我试图在任务窗格打开或关闭时触发一些代码。为了处理各种各样的窗口,我实现了一个与此非常相似的结构 ThisAddIn.cs包含以下类 public class TaskPaneManager { static Dictionary<string, Microsoft.Office.Tools.CustomTaskPane> _cr

我目前正在VSTO2015和Excel 2016中开发一个应用程序。该应用程序在不同的窗口中管理多个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];
        }
    ....
问题:事件处理程序 我无法启动事件处理程序。我不知道我做错了什么。在
TaskPaneDesigner
中,我使用
this.VisibleChanged+=new System.EventHandler(this.TaskPaneUploadWizard\u VisibleChanged)附加事件
,然后在my
TaskPaneUploadWizard
类中定义它,如下所示

public partial class TaskPaneUploadWizard : UserControl
{
    ...

    public TaskPaneUploadWizard()
    {
        InitializeComponent();
    }

    private void TaskPaneUploadWizard_VisibleChanged(object sender, EventArgs e)
    {
        // Some code
    }
我的想法 在我看来,似乎我正在将eventHandler附加到除
CustomTaskPane
对象之外的其他对象,或者在创建
CustomTaskPane
之前附加它


救命啊

要检测任务窗格是否已打开或关闭,您必须附加到
窗格的
VisibleChanged
事件

因此,最简单的解决方案是只向
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;
现在,整个任务窗格的可见性将传递给其内容,并且应该执行一些代码

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

pane.VisibleChanged += (s, e) => { /* some code */ };
但就个人而言,我宁愿推荐第一种方法,因为它似乎更适合您现有的代码

var UploadWizardTaskpane = TaskPaneManager.GetTaskPane(title, title, () => new TaskPaneUploadWizard());
这是在创建
CustomTaskPane
而不是
TaskPaneUploadWizard
对象

看起来像是
this.VisibleChanged+=new System.EventHandler(this.TaskPaneUploadWizard\u VisibleChanged)
正在执行
TaskPaneUploadWizard
操作,该向导仅是
CustomTaskPane

请注意自定义任务窗格的可见性
不会影响
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
    }
    //{---}
我的建议 如果从设计器中删除
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;
//{---}

@用户3465779不客气,很高兴我能帮助你!:-)