c# – Excel中的CustomTaskPane不会显示在新的工作簿中

我已经添加一个CustomTaskPane到Excel 2013,让用户快速搜索照片.如果用户只打开/创建一个工作簿,它的工作正常.问题是如果他们打开另一个工作簿或创建一个新的工作簿,任务窗格不会出现在出现的新窗口中.它只是保留在原来的窗口.我知道这个行为是由于我只是在打开Excel时初始化面板.当ActiveWindow事件打开另一个工作簿时,我添加一个事件处理程序来初始化一个新的面板.

问题是我不知道如何判断CustomTaskPane是否已经存在于窗口中.如果是这样,它会创建另一个CustomTaskPane,所以在该窗口中现在有两个.我写了以下代码来处理原来的并创建一个新的代码,但是它会引入一些滞后(1-5秒),这会使用户每次更换工作簿窗口时都会疯狂.有没有办法查看窗口中是否已经存在CustomTaskPane,以避免处理和重新创建一个新的,以避免堆叠重复的任务窗格?

Microsoft.Office.Tools.CustomTaskPane PartPhotoTaskPane;
Globals.ThisAddIn.Application.WindowActivate += Application_WindowActivate;

        void Application_WindowActivate(Excel.Workbook Wb,Excel.Window Wn)
    {
        if (PartPhotoTaskPane != null)
        {
            PartPhotoTaskPane.dispose();
            InitalizePartPhotoViewerTaskPane(EPPF);
        }
        else
        {
            InitalizePartPhotoViewerTaskPane(EPPF);
        }
    }

    /// <summary>
    /// Start up the part photo viewer task pane
    /// </summary>
    private void InitalizePartPhotoViewerTaskPane(ExcelPartPhotoFunctions _EPPF)
    {
        //intialize the part search
        try
        {
            PartPhotoTaskPane = Globals.ThisAddIn.CustomTaskPanes.Add(new PartPhotoSearchPane(_EPPF),"Part information",Globals.ThisAddIn.Application.ActiveWindow);
            PartPhotoTaskPane.Visible = Properties.Settings.Default.InfoPaneOpenStatus;
            PartPhotoTaskPane.Width = 260;
        }
        catch (Exception e)
        {
            MessageBox.Show("Error starting Part Info Toolbar:" + Environment.NewLine +
            e.Message + Environment.NewLine + e.StackTrace,"Error!",MessageBoxButtons.OK,MessageBoxIcon.Error);
        }
    }

解决方法

使用hwnd(Globals.ThisAddIn.Application.Hwnd)来标识Excel窗口.对于Office2013(使用SDI方法)和使用MDI窗口的较旧版本的Office,这将非常有效.这是一个你可以使用的类:
public class TaskPaneManager
{
    static Dictionary<string,CustomTaskPane> _createdPanes = new Dictionary<string,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 CustomTaskPane GetTaskPane(string taskPaneId,string taskPaneTitle,Func<UserControl> taskPaneCreatorFunc)
    {
        string key = string.Format("{0}({1})",taskPaneId,Globals.ThisAddIn.Application.Hwnd);
        if (!_createdPanes.ContainsKey(key))
        {
            var pane = Globals.ThisAddIn.CustomTaskPanes.Add(taskPaneCreatorFunc(),taskPaneTitle);
            _createdPanes[key] = pane;
        }
        return _createdPanes[key];
    }
}

这里我实际上结合Excel窗口hwnd和一些任意的字符串标识符来标识任务窗格.这个想法是在同一个插件支持多个任务窗口.

以下是从功能区如何使用它的示例:

private void button1_Click(object sender,RibbonControlEventArgs e)
    {
        var taskpane = TaskPaneManager.GetTaskPane("A","Task pane type A",() => new UserControl1());
        taskpane.Visible = !taskpane.Visible;
    }

    private void button2_Click(object sender,RibbonControlEventArgs e)
    {
        var taskpane = TaskPaneManager.GetTaskPane("B","Task pane type B",() => new UserControl2());
        taskpane.Visible = !taskpane.Visible;
    }

如果在Excel中打开多个工作簿,Excel窗口将有自己的taspaneA和taskpaneB.

相关文章

C#项目进行IIS部署过程中报错及其一般解决方案_c#iis执行语句...
微信扫码登录PC端网站应用的案例(C#)_c# 微信扫码登录
原文地址:http://msdn.microsoft.com/en-us/magazine/cc163...
前言 随着近些年微服务的流行,有越来越多的开发者和团队所采...
最近因为比较忙,好久没有写博客了,这篇主要给大家分享一下...
在多核CPU在今天和不久的将来,计算机将拥有更多的内核,Mic...