【问题标题】:Trouble attaching an event to a custom task pane. VSTO, Excel 2016将事件附加到自定义任务窗格时出现问题。 VSTO,Excel 2016
【发布时间】:2017-10-04 20:54:01
【问题描述】:

背景

我目前正在开发 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 之前附加它。

救命!

【问题讨论】:

    标签: c# excel vsto


    【解决方案1】:

    要检测任务窗格是打开还是关闭,您必须附加到paneVisibleChanged 事件。

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

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

    【讨论】:

    • @user3465779 不客气,很高兴能帮到你! :-)
    【解决方案2】:
    var UploadWizardTaskpane = TaskPaneManager.GetTaskPane(title, title, () => new TaskPaneUploadWizard());
    

    这是在创建 CustomTaskPane 而不是 TaskPaneUploadWizard 对象

    似乎this.VisibleChanged += new System.EventHandler(this.TaskPaneUploadWizard_VisibleChanged); 正在作用于TaskPaneUploadWizard,这只是CustomTaskPane 的客人

    请注意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;
    //{---}
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-10
      • 2018-11-14
      • 2022-11-01
      • 2011-06-15
      • 1970-01-01
      相关资源
      最近更新 更多