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

时间:2017-10-03 16:23:14

标签: c# excel vsto

背景

我目前正在开发VSTO2015和Excel 2016中的应用程序。该应用程序在不同的窗口中管理许多CustomTaskPanes。我打算在打开或关闭任务窗格时触发// some code。为了处理各种窗口,我实现了一个与此非常相似的结构;

CustomTaskPane in Excel doesn't appear in new Workbooks

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);附加活动,然后在我的TaskPaneUploadWizard课程中定义,如下所示;

public partial class TaskPaneUploadWizard : UserControl
{
    ...

    public TaskPaneUploadWizard()
    {
        InitializeComponent();
    }

    private void TaskPaneUploadWizard_VisibleChanged(object sender, EventArgs e)
    {
        // Some code
    }

我的想法

在我看来好像我要将eventHandler附加到CustomTaskPane对象之外的其他内容,或者我在创建CustomTaskPane之前附加它。

帮助!

2 个答案:

答案 0 :(得分:1)

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

所以最简单的解决方案是只向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 */ };

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

答案 1 :(得分:0)

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

这是创建CustomTaskPane而不是TaskPaneUploadWizard对象

似乎this.VisibleChanged += new System.EventHandler(this.TaskPaneUploadWizard_VisibleChanged);代表TaskPaneUploadWizardCustomTaskPane

的客人

请注意 CustomTaskPane的曝光度不会影响TaskPaneUploadWizard

我的建议

您从设计器中删除了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;
//{---}