Excel自定义任务窗格未显示。

7

我正在一个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 只是根据 MSDN 上的文档一个 UserControlhttp://msdn.microsoft.com/en-us/library/aa942846.aspx

我认为展示如何定义CellTaskPane可能会有所帮助。我用MSDN的一个例子快速模拟了一下,并使用以下定义成功地完成了它:public class CellTaskPane : System.Windows.Forms.UserControl { ....etc... - Richard Hansell
@RichardHansell 这只是一个标准的用户控件,符合 http://msdn.microsoft.com/en-us/library/aa942846.aspx 上的文档。 - Clint
1
我在几个地方读到的一件事是,如果你已经配置了Excel在启动时自动加载文件,那么这可能会“干扰”自定义任务窗格。例如,如果你有一个名为“Personal.xls”的文件或者任何隐藏在“XLStartup”中的文件,那么暂时禁用它们可能是值得的。 - Richard Hansell
@RichardHansell 很不幸,在 XLStart 文件夹或他通过在互联网上搜寻发现的其他许多位置中都没有找到任何内容... - Clint
10个回答

4
原来我们没有直接处理它!原来是安装了另一个插件(第三方),出于某种奇怪的原因,这个插件干扰了面板的显示(不知道为什么或如何实现)。可惜Excel没有显示任何错误或至少抛出异常。唉。

1
嗨 Clint -- 你知道是哪个第三方插件吗?我们的插件和 Oracle SmartView 也出现了同样的问题。当启用 SmartView 时,我们的 CustomTaskPane 窗口只有在没有工作表打开时才可见(它们似乎被隐藏在工作表后面)。 - Eric Hirst
嗨,克林特 - 我已禁用所有的Add-Ins(COM+和Excel),按原样复制了下面的代码,但仍无法显示自定义任务窗格。 - Doug Kimzey

3
我建议首先尝试一个非常简单的自定义任务窗格,以查看是否有效。我设计了一个最简单的示例,基本上只是一个文本框,在将值推入其中并在按下按钮时将其返回到功能区中。
如果您要尝试这个示例,则可以创建一个新的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
    }
}

添加一个名为CellTaskPane.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 上示例的混合版本。如果您愿意,您可能也可以自己实现这个功能?无论如何,这将使您能够查看更复杂的功能区中是否存在任何问题…或者这是否是您同事计算机的根本问题。

很不幸,我已经有的任务窗格非常简单,只是一些标签,我正在设置值,没有什么特别的:/ - Clint
好的,你能与不可见的任务窗格进行通信吗?即使你实际上看不到它,你能够设置或返回其中一个字段的值吗? - Richard Hansell
是的,我在功能区上有一个切换按钮,并调用窗格并检查“Visible”属性,然后使用它来驱动切换按钮的选中状态,因为它被切换到打开状态,所以显然它认为窗格存在。 - Clint
你尝试过将自定义任务窗格设置为浮动状态而非停靠状态吗? - Richard Hansell
我已经找到了问题所在,我已经点赞了这个答案,以便在悬赏过期时您能获得奖励。感谢您的帮助! - Clint
显示剩余2条评论

3

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

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

enter image description here

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


这也是我们经常看到的情况,我们有一个由公司提供的启动工作簿,它会完全阻止我们的自定义插件运行,因此,其他插件和启动工作簿都可能会引起问题! - Clint

2
为每个工作簿创建一个新的任务窗格实例。对您的代码进行以下更改,即可使任务窗格即使在启用插件的情况下也能正常工作。
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);
}

2
在尝试获取“教程:将自定义任务窗格与功能区按钮同步”微软示例代码时,我遇到了这个问题。以下是该页面的链接:http://msdn.microsoft.com/en-us/library/bb608590.aspx。经过多次重新开始和搜索互联网寻找线索,我发现了这个问题和Clint的答案——一个插件导致了他的问题。我启用了一些插件,但通过一些试错,我找到了罪魁祸首:微软自己的“分析工具包”!一旦我禁用了分析工具包,自定义窗格就会如预期般出现和消失。所以,正如Clint所发现的那样,如果您遇到这个问题,您应该尝试的第一件事可能是禁用所有插件,看看是否解决了问题。如果是这样,然后您可以返回并开始打开它们,直到找到干扰您自定义窗格可见性的插件。

也为我安装Analysis Toolpack。我不得不重新启动Excel。 - ThunderFrame

1

如果你发现即使关闭了所有其他插件,任务窗格仍然没有显示出来,那可能是因为它加载在你的“Personal.xlsb”工作簿中。在关闭它后,我尝试重新使窗格可见,但收到了一个错误提示说它已经被关闭了。


1

好的,在遵循@GaryP的建议、禁用其他插件以及认为我已经解决了问题(虽然无法访问我的其他插件),我发现每当我打开多个工作簿时,插件就会消失。

但是在那时,我不仅收到了缺少任务窗格或静默失败的消息,实际上还收到了一个错误:

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

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

根本原因是使用了2013年及以后版本中的SDI

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


0

我曾经遇到过同样的问题,但是禁用分析工具包并没有解决它。相反,我不得不将XLAM文件移出其安装文件夹(打破对它的引用,因为你无法通过Excel删除它),然后它开始正常工作。

后来我又把这些文件添加回去了,它仍然可以正常工作。激活插件确实会导致我的自定义任务栏出现问题。不确定这个长期解决方案是什么。


0

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

https://learn.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”代码。

-1

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

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

在此之后,再次尝试加载该插件。然后,逐个添加所需的内容并进行测试。它们可能会再次破坏它,也可能不会,目前似乎没有关于哪种插件会或不会破坏任务窗格的共识。

如果有人发现更多查找插件的地方,我将把它们添加到列表中。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接