前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Excel催化剂开源第5波-任务窗格在OFFICE2013中新建文档不能同步显示问题解决

Excel催化剂开源第5波-任务窗格在OFFICE2013中新建文档不能同步显示问题解决

作者头像
Excel催化剂
发布2021-08-19 14:57:22
6610
发布2021-08-19 14:57:22
举报
文章被收录于专栏:Excel催化剂

在OFFICE2013及之后,使用了单文档界面技术,不同于以往版本可以共享任务空格、功能区。所以当开发任务窗格时,需要考虑到每一个工作薄都关联一个任务窗格。

背景介绍

单文档界面摘录官方定义如下: 对 Excel 2013 中的单文档界面 (SDI) 进行更改对可编程性具有一定影响。SDI 意味着每个工作簿都将有其自己的顶级应用程序窗口,并将有自己的相应功能区。

带来的好处是不同工作薄可以精细控制不同的显示,例如工作薄A,显示功能区Tab1,工作薄B显示功能区Tab2,区分对待不同文档所使用的功能。

带来的不便之处就是要每个文档都要考虑关联对应的界面,特别是任务窗格。

具体代码实现

Excel催化剂插件也大量使用了任务窗格,为了让用户在作配置信息时,可以更灵活,不必每次都弹出一个窗体来配置,只有需要配置时,才转到任务窗格中配置,否则保留默认的配置,并且默认配置可以让用户在任务窗格上查看。

所以用了任务窗格,需要做版本兼容性,即区分Excel2013及之后的版本的SDI特性。

下面截取关键代码,以Excel工作薄的工作表导航功能为例,作简单解释

工作表导航任务窗格

先初始化字典变量

代码语言:javascript
复制
        private static void InialTaskPanel()
        {
            Utilities.TaskPanelUtility.CustomTaskPanesOfWorksheetNavigation = new Dictionary<int, Microsoft.Office.Tools.CustomTaskPane>();
            Utilities.TaskPanelUtility.UscWorksheetNavigations = new Dictionary<int, UscWorksheetNavigation>();
        }

根据不同版本的Excel启用不同方法

代码语言:javascript
复制
        private void tgbShowActionPanel_Click(object sender, RibbonControlEventArgs e)
        {
            RibbonToggleButton tgb = sender as RibbonToggleButton;
            try
            {
                if (Single.Parse(Common.ExcelApp.Version) >= 15)
                {

                    WorksheetNavigate.ShowCustomTaskPanelOfWorksheetNavigationOfExcel2013(tgb.Checked);
                }
                else
                {
                    WorksheetNavigate.ShowCustomTaskPanelOfWorksheetNavigationOfExcel2010(tgb.Checked);
                }
                //将工作表导航的显示状态保存起来
                Properties.Settings.Default.IsPaneVisible = tgb.Checked;
                Properties.Settings.Default.Save();
            }
            catch (Exception ex)
            {
                Common.OutMsgError(ex);
            }
        }

重点是2013版的方法,关键之处是拿到当前的活动窗体的句柄,通过字典查找是否已经创建过,没创建就新建,新建完要把它句柄存入到字典中。

代码语言:javascript
复制
        public static void ShowCustomTaskPanelOfWorksheetNavigationOfExcel2013(bool isPaneVisible)
        {
            int hwndCustomTaskPane = Common.ExcelApp.ActiveWindow.Hwnd;
            Microsoft.Office.Tools.CustomTaskPane activeCustomTaskPane;
          Utilities.TaskPanelUtility.CustomTaskPanesOfWorksheetNavigation.TryGetValue(hwndCustomTaskPane, out activeCustomTaskPane);
            if (activeCustomTaskPane == null)
            {
                UscWorksheetNavigation uscWorksheetNavigation = new UscWorksheetNavigation();
                activeCustomTaskPane = Globals.ThisAddIn.CustomTaskPanes.Add(uscWorksheetNavigation, "工作表导航", Globals.ThisAddIn.Application.ActiveWindow);
                activeCustomTaskPane.DockPosition = Office.MsoCTPDockPosition.msoCTPDockPositionLeft;
                activeCustomTaskPane.Width = 300;

                activeCustomTaskPane.VisibleChanged += ActiveCustomTaskPane_VisibleChanged;
                activeCustomTaskPane.Visible = isPaneVisible;
                Utilities.TaskPanelUtility.CustomTaskPanesOfWorksheetNavigation.Add(hwndCustomTaskPane, activeCustomTaskPane);
                Utilities.TaskPanelUtility.UscWorksheetNavigations.Add(hwndCustomTaskPane, uscWorksheetNavigation);
            }
            else
            {
                activeCustomTaskPane.Visible = isPaneVisible;
                if (isPaneVisible)
                {
                    Utilities.TaskPanelUtility.UscWorksheetNavigations[hwndCustomTaskPane].ReLoadWorksheetName();
                }
            }
        }

因工作表导航,每切换一次工作薄,都要更新下工作表清单,所以订阅了一个窗体切换事件,其他场景可能不必这样做,只需订阅个打开文件事件即可。

代码语言:javascript
复制
        private void ExcelApp_WindowActivate(Excel.Workbook Wb, Excel.Window Wn)
        {
            try
            {
                if (Common.ExcelApp.ActiveWorkbook.ProtectStructure == false)
                {
                    bool isPaneVisible = Properties.Settings.Default.IsPaneVisible;

                    if (Single.Parse(Common.ExcelApp.Version) >= 15)
                    {
                        int hwndCustomTaskPane = this.Application.ActiveWindow.Hwnd;
                        WorksheetNavigate.ShowCustomTaskPanelOfWorksheetNavigationOfExcel2013(isPaneVisible);
                    }
                    else
                    {
                        WorksheetNavigate.ShowCustomTaskPanelOfWorksheetNavigationOfExcel2010(isPaneVisible);
                    }
                }
            }
            catch (Exception)
            {

            }

        }

其他的非关键代码,自己把握如何写就行,笔者写代码也有限,只能抛砖引玉了。

结语

通过直接的源代码讲解,希望对Excel开发的朋友们可以带来一些帮助,具体原理之外的东西,可自由发挥。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-01-06,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Excel催化剂 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 背景介绍
  • 具体代码实现
  • 结语
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档