【问题标题】:Excel Custom Task Pane not showingExcel 自定义任务窗格未显示
【发布时间】:2014-08-25 23:55:18
【问题描述】:

我在 excel VSTO 加载项中显示了一个自定义任务窗格,我正在构建它并显示如下:

var ctrl = new CellTaskPane();
var pane = CustomTaskPanes.Add(ctrl, "Custom Sheet");
pane.DockPosition = Office.MsoCTPDockPosition.msoCTPDockPositionRight;
pane.DockPositionRestrict = Office.MsoCTPDockPositionRestrict.msoCTPDockPositionRestrictNoChange;
pane.Visible = true;

这是在 ThisAddin.cs 文件中完成的,它在我的机器上运行良好,无论是在调试会话下还是通过单击一次安装程序安装的加载项。

但是,在同事的机器上安装插件很麻烦。

加载项运行正常,上下文菜单/功能区运行良好,但窗格拒绝显示。

我在功能区上有一个切换按钮,它可以切换窗格上的 Visible 属性,即使单击它也不会强制显示窗格。

我们将不胜感激,Google 对此毫无用处。

谢谢。


我应该提到 CellTaskPane 只是一个 UserControl 根据 MSDN 上的文档:http://msdn.microsoft.com/en-us/library/aa942846.aspx

【问题讨论】:

  • 我认为展示您如何定义 CellTask​​Pane 可能会有所帮助?我用 MSDN 中的一个示例快速模拟了这一点,它适用于以下定义: public class CellTask​​Pane : System.Windows.Forms.UserControl { ....etc...
  • @RichardHansell 它只是一个标准的用户控件,根据文档在:msdn.microsoft.com/en-us/library/aa942846.aspx
  • 我在几个地方读到的一件事是,如果您将 Excel 配置为在启动时自动加载文件,那么这可能会“干扰”自定义任务窗格。例如,如果您有一个“Personal.xls”或任何隐藏在“XLStartup”中的东西,那么暂时禁用这些可能值得吗?
  • @RichardHansell 不幸的是,XLStart 文件夹中没有任何内容,或者他在互联网上四处寻找的许多其他位置都没有...

标签: excel vsto excel-2013 excel-addins customtaskpane


【解决方案1】:

我知道这已经很老了,但它对任何可能寻找答案的人都有用,但我们开始吧: 如果您在 ThisAddIn_Startup 下添加新任务窗格,它只会在 Excel 开始时添加一次,并且不会出现在任何其他 Excel 会话中,因此基于以下显示如何处理多个会话的链接:

https://docs.microsoft.com/en-us/previous-versions/office/developer/office-2007/bb264456(v=office.12)?redirectedfrom=MSDN#Anchor_2

我得出的结论是,我应该在需要任务窗格时可以触发的其他事件下创建一个新的任务窗格,然后验证当前窗口是否具有任务窗格,如果没有则创建一个新的并显示它。该事件可以是任何触发器,如功能区按钮、打开文档等。

Dim CurrentTaskPane As Microsoft.Office.Tools.CustomTaskPane = Nothing
Globals.ThisAddIn.RemoveOrphanedTaskPanes() 'to remove any unused taskpane
For Each ctp As Microsoft.Office.Tools.CustomTaskPane In Globals.ThisAddIn.CustomTaskPanes
    If ctp.Window.Hwnd = Excel.Application.ActiveWindow.Hwnd Then
       CurrentTaskPane = ctp
       Exit For
    End If
Next
If CurrentTaskPane Is Nothing Then
    CurrentTaskPane = Globals.ThisAddIn.CustomTaskPanes.Add(New ControlName, "My TaskPane", Excel.Application.ActiveWindow)
End If
CurrentTaskPane.Visible = True

您可以从提供的链接中找到“RemoveOrphanedTaskPanes”代码。

【讨论】:

    【解决方案2】:

    如果您发现即使在关闭所有其他加载项后,TaskPane 仍然不显示,可能是因为它已加载到您的“Personal.xlsb”工作簿中。关闭它后,我尝试让窗格再次可见,我收到一个错误,它已被关闭。

    【讨论】:

      【解决方案3】:

      为每个工作簿创建一个新的任务窗格实例。对您的代码进行以下更改,即使启用了插件,任务窗格也能正常工作。

      private void Application_WorkbookActivate(Microsoft.Office.Interop.Excel.Workbook wb)
      {
          pane = CustomTaskPanes.Add(ctrl, "Custom Sheet");
          pane.DockPosition = Office.MsoCTPDockPosition.msoCTPDockPositionRight;
          pane.DockPositionRestrict = Office.MsoCTPDockPositionRestrict.msoCTPDockPositionRestrictNoChange;
          pane.Visible = true;
          pane.VisibleChanged += new EventHandler(taskPaneValue_VisibleChanged);
          ctrl.SetName("test");
      }
      
      private void ThisAddIn_Startup(object sender, System.EventArgs e)
      {
          this.Application.WorkbookActivate += new Excel.AppEvents_WorkbookActivateEventHandler(
              Application_WorkbookActivate);
      }
      

      【讨论】:

        【解决方案4】:

        总结其他答案:这似乎是由于加载了其他加载项、.XLAM 文件等。这些可以从许多不同的地方加载,您需要全部检查并删除它们。您可以稍后重新启用它们,因此请备份所有内容。这是一个清单:

        1. 文件 -> 选项 -> 高级 -> 常规 -> “启动时,打开所有文件...” 删除这些文件并禁用该选项。
        2. 文件 -> 选项 -> 加载项 -> 检查所有活动的应用程序加载项。在对话框底部附近,使用管理:Excel/Com 加载项查看加载项并禁用或删除它们。甚至微软包含的也可能导致它,所以也禁用它们。它们不允许您删除它们,这很好,只要它们被禁用。
        3. C:\Users\$USERNAME\AppData\Roaming\Microsoft\Excel\XLSTART 从此目录中删除所有文件。
        4. C:\Users\$USERNAME\AppData\Roaming\Microsoft\AddIns 从此目录中删除所有文件。

        在此之后,再次尝试加载加载项。然后,将需要的东西一一添加回来,继续测试。他们可能会再次破坏它,也可能不会,对于哪种加载项会破坏任务窗格和不会破坏任务窗格似乎没有达成共识。

        如果有人发现更多地方可以寻找加载项,我会将它们添加到列表中。

        【讨论】:

          【解决方案5】:

          好吧,在遵循 @GaryP 的建议、禁用我的其他加载项并认为我已经解决了问题(尽管无法访问我的其他加载项)之后,我发现每当我打开多个工作簿时,加载项都会消失。

          但在那一点上,我不仅得到了一个丢失的任务窗格或一个静默失败,我实际上得到了一个错误:

          任务窗格已被删除或不再有效

          因此,似乎禁用加载项本身并不能解决问题,而是禁用加载项正在减少打开的工作簿的数量(即使加载项不可见,它们仍然可以有一个功能区句柄)...

          根本原因是使用了SDI in 2013 and later

          所以,现在我可以加载所有加载项了。

          【讨论】:

            【解决方案6】:

            我遇到了同样的问题,并没有通过禁用分析工具包来解决它,而是我不得不将 XLAM 从其安装的文件夹中移出(打破对它的引用,因为您无法通过 Excel 将其删除) 并且它开始工作了。

            我感觉已将文件添加回来并且它继续工作。激活插件确实会导致我的自定义任务栏中断。不确定这个长期修复是什么。

            【讨论】:

              【解决方案7】:

              我遇到了同样的问题,但不是我可以禁用的任何插件(COM+ 或 Excel)。

              我已将我的 excel 配置为在启动时打开文件 (Excel 选项 -> 高级 -> 常规)

              在那里,我有一个自定义功能区的 .XLAM。 当我清除此配置时,我的插件开始工作。

              【讨论】:

              • 这也是我们经常看到的事情,我们有一个公司提供的启动工作簿,它会阻止我们的自定义插件完全运行,所以是的,其他插件和启动工作簿都会导致问题!
              【解决方案8】:

              我在尝试让“演练:使用功能区按钮同步自定义任务窗格”的 Microsoft 示例代码时遇到了这个问题。这是该页面的链接:

              http://msdn.microsoft.com/en-us/library/bb608590.aspx

              在从头开始大约三遍并在 Internet 上搜索关于我可能做错了什么的线索后,我遇到了这个问题和 Clint 的回答,即加载项导致了他的问题。我启用了一些加载项,但经过反复试验,我找到了罪魁祸首:微软自己的“分析工具包”!

              禁用分析工具包后,自定义窗格开始按预期出现和消失。

              因此,正如 Clint 发现的那样,如果遇到此问题,您可能应该尝试的第一件事是禁用所有加载项,看看是否能解决问题。如果是这样,那么您可以返回并开始打开它们,直到找到干扰您的自定义窗格可见性的那个。

              【讨论】:

              • 分析工具包也适合我。必须重新启动 Excel。
              【解决方案9】:

              原来这不是我们直接做的!

              安装了另一个插件(第三方),由于某种奇怪的原因干扰了正在显示的窗格(不知道为什么或如何)。

              遗憾的是 Excel 没有显示任何类型的错误或至少引发异常。

              嗯。

              【讨论】:

              • 嗨,克林特——知道是哪个第 3 方插件吗?我们在插件和 Oracle SmartView 中看到了同样的问题。启用 SmartView 后,我们的 CustomTaskPane 窗口仅在没有打开工作表时可见(它们似乎隐藏在工作表后面)。
              • 嗨 Clint - 我已禁用所有加载项(COM+ 和 Excel),按原样复制下面的代码,但仍然无法显示自定义任务窗格。
              【解决方案10】:

              我建议您先尝试一个非常非常简单的自定义任务窗格,看看是否可行。我把我能想到的最简单的例子放在一起,基本上是一个文本框,它获取一个值,当按下按钮时,它会返回到功能区。

              如果您要尝试此方法,那么我会将其作为新的解决方案。使用“设计器模式”功能区创建一个新的 VSTO 项目。在其下方添加一个切换按钮和一个普通按钮。然后复制这段代码:

              ThisAddIn.cs

              using System;
              using Office = Microsoft.Office.Core;
              
              namespace ExcelAddIn1
              {
                  public partial class ThisAddIn
                  {
                      private Microsoft.Office.Tools.CustomTaskPane pane;
                      private CellTaskPane ctrl = new CellTaskPane();
              
                      private void ThisAddIn_Startup(object sender, System.EventArgs e)
                      {
                          pane = CustomTaskPanes.Add(ctrl, "Custom Sheet");
                          pane.DockPosition = Office.MsoCTPDockPosition.msoCTPDockPositionRight;
                          pane.DockPositionRestrict = Office.MsoCTPDockPositionRestrict.msoCTPDockPositionRestrictNoChange;
                          pane.Visible = true;
                          pane.VisibleChanged += new EventHandler(taskPaneValue_VisibleChanged);
                          ctrl.SetName("test");
                      }
              
                      private void taskPaneValue_VisibleChanged(object sender, System.EventArgs e)
                      {
                          Globals.Ribbons.Ribbon1.toggleButton1.Checked = pane.Visible;
                      }
              
                      public Microsoft.Office.Tools.CustomTaskPane TaskPane
                      {
                          get
                          {
                              return pane;
                          }
                      }
              
                      public CellTaskPane MyContainer
                      {
                          get
                          {
                              return ctrl;
                          }
                      }
              
                      private void ThisAddIn_Shutdown(object sender, System.EventArgs e)
                      {
                      }
              
                      #region VSTO generated code
              
                      /// <summary>
                      /// Required method for Designer support - do not modify
                      /// the contents of this method with the code editor.
                      /// </summary>
                      private void InternalStartup()
                      {
                          this.Startup += new System.EventHandler(ThisAddIn_Startup);
                          this.Shutdown += new System.EventHandler(ThisAddIn_Shutdown);
                      }
              
                      #endregion
                  }
              }
              

              添加一个名为 CellTask​​Pane.cs 的新类:

              using System;
              using System.Windows.Forms;
              using System.Drawing;
              using System.ComponentModel;
              
              namespace ExcelAddIn1
              {
                  public class CellTaskPane : System.Windows.Forms.UserControl
                  {
                      public System.Windows.Forms.TextBox test;
              
                      public CellTaskPane()
                      {
                          InitializeComponent();
                      }
              
                      public void InitializeComponent()
                      {
                          test = new System.Windows.Forms.TextBox();
                          test.Location = new System.Drawing.Point(120, 8);
                          test.Size = new System.Drawing.Size(232, 20);
                          test.TabIndex = 0;
                          Controls.AddRange(new System.Windows.Forms.Control[] { test });
                          Size = new System.Drawing.Size(375, 150);
                      }
              
                      public void SetName(string text)
                      {
                          test.Text = text;
                      }
              
                      public string GetName()
                      {
                          return test.Text;
                      }
                  }
              }
              

              将以下代码添加到 Ribbon1.cs:

              using System;
              using Microsoft.Office.Tools.Ribbon;
              
              namespace ExcelAddIn1
              {
                  public partial class Ribbon1
                  {
                      private void toggleButton1_Click(object sender, RibbonControlEventArgs e)
                      {
                          Globals.ThisAddIn.TaskPane.Visible = ((RibbonToggleButton)sender).Checked;
                      }
              
                      private void button1_Click(object sender, RibbonControlEventArgs e)
                      {
                          button1.Label = Globals.ThisAddIn.MyContainer.GetName();
                      }
                  }
              }
              

              显然,您需要进行一些调整才能使其正常工作,我尝试为新项目和按钮采用默认名称。

              当你运行它时,你应该得到一个自定义任务窗格。当您切换到“TabAddIn”并单击切换按钮时,它应该显示/隐藏任务窗格。当您单击普通按钮时,应将任务窗格中唯一字段的内容复制为按钮名称。我将其默认为“测试”,因此即使任务窗格不可见,您也可以查看它是否在内存中?

              我对此进行了测试,它似乎工作正常。基本上,这只是 MSDN 上示例的修改版本。如果你愿意,你可以自己做这个吗?如果没有其他问题,这将使您能够查看您正在处理的更复杂的功能区中是否有任何问题导致问题......或者这是否是您同事机器的根本问题。

              【讨论】:

              • 不幸的是我的任务窗格已经很简单了,只是我设置值的几个标签,没什么特别的:/
              • 好的,您可以与不可见的任务窗格进行通信吗,即即使您实际上看不到它,也可以为其上的某个字段设置或返回一个值?
              • 是的,我在功能区上有一个切换按钮,我正在调用窗格并检查 Visible 属性并使用它来驱动切换按钮的选中状态,它已切换-on 如此清晰,它认为窗格在那里。
              • 您是否尝试过让自定义任务窗格浮动而不是停靠?
              • 我发现出了什么问题,我赞成这个答案,以便您在它到期时获得赏金。感谢您的帮助!
              猜你喜欢
              • 2023-03-09
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多