2017-07-27 54 views
0

我开发了Excel的VSTO 4加载项。它的工作原理非常完美,但是,我有一个按钮放置在最初禁用的Ribbon控件的自定义选项卡中。无法以编程方式启用功能区按钮

在我的自定义选项卡中单击其他功能区按钮后,我需要启用最初禁用的按钮。

我试着用:

btnCancelar.Visible = true; 

在按钮的Click事件,但按钮不会显示。奇怪的是,在调试时,它仍然没有出现,但是如果显示了一个MessageBox,那么该按钮最终会变得可见。

我不明白这种行为。如何通过代码动态地启用或禁用功能区按钮?

回答

0

我已经为此创建了解决方法。

很简单。刚开始不同线程的长时间运行过程。这样,取消按钮会在应用程序中显示,然后在处理结束后隐藏。

我用这个代码启动过程中Ribbon.cs代码:

btnCancelar.Visible = true; 

Action action =() => { 
          Formatter.GenerateNewSheet(Formatter.TargetType.ImpresionEtiquetas, frm.CustomerID, workbook, btnCancelar); 
         }; 
System.Threading.Tasks.Task.Factory.StartNew(action); 

,过程方法里面我有这样的代码:

public static bool GenerateNewSheet(TargetType type, string customerID, Excel.Workbook workbook, Microsoft.Office.Tools.Ribbon.RibbonButton btnCancelar) 
    { 
     try 
     { 
      _cancelled = false; 
      InfoLog.ClearLog(); 

      switch (type) 
      { 
       case TargetType.ImpresionEtiquetas: 
        return GenerateTagPrinting(customerID, workbook); 
      } 

      return false; 
     } 
     finally 
     { 
      btnCancelar.Visible = false; 
     } 
    } 

这里的有趣的事情,我已经发现Excel是线程安全的,因此在新工作表中添加行或者将Visible属性再次设置为false时,不需要添加同步机制。

问候

海梅

0

我不确定你的项目中使用了什么语言,但我想你可以将它转换为你自己使用的语言。我会在这里显示的例子在C#:

首先,你需要实现在RibbonXML定义所谓的回调函数:

<button id="buttonSomething" label="Content" size="large" getVisible="EnableControl"/> 

那么下一步就是实现回调函数:

public bool EnableControl(IRibbonControl control) 
{ 
    return true; // visible ... false = invisible 
} 

VSTO将触发getVisible回调,并根据返回值启用或禁用可见状态(不要忘记从RibbonXML中删除任何可见属性,否则回调不会被触发)

如果功能区设计器需要确保您的点击签名是正确的,那么简单的方法是双击功能区设计器上的按钮。这将为您创建Click方法,例如:

我使用Ribbon设计器创建了一个Ribbon并添加了两个按钮。双击第一个按钮以获得如下所示的空方法,并添加代码。

private void button1_Click(object sender, RibbonControlEventArgs e) 
    { 
     // Toggle button visibility and make sure the button is enabled 
     // Visible (obviously) makes it visible, while Enabled is grayed if 
     // false. You don't need this it is Enabled by default, so just for 
     // demo purposes 

     button2.Visible = !button2.Visible; 
     button2.Enabled = button2.Visible; 

     // Force Ribbon Invalidate ... 
     this.RibbonUI.Invalidate(); 

     // Long running proces 
    } 

这对我很好,所以如果它不适合你,请提供你的编码的更多细节。

+0

你好...我使用C#,以及...但是,我找不到在哪里添加回调。我没有RibbonXML ....我用丝带设计师。我该如何添加回调? – jstuardo

+0

使用Ribbon设计器(稍微不灵活但适用于大多数解决方案)更容易,除非您为方法创建了正确的“签名”。看到我编辑的答案 –

+0

当然,它适合你。如果我使用你的代码,它也可以工作。问题是这样的:在使按钮可见之后,我开始了一个长时间运行的过程。该过程用数据填充新工作表。我希望用户能够取消该过程......这就是为什么我需要在过程开始之前显示取消按钮的原因。但即使当我使用Application.DoEvents,button.Invalidate和更多的尝试,当返回当前方法时,最终显示按钮。奇怪的是,Excel在处理过程中没有被锁定,因为我可以看到行是如何填充的。 – jstuardo