无法以编程方式启用功能区按钮
Cannot enable a Ribbon button programmatically
我为 Excel 开发了一个 VSTO 4 插件。它工作完美,但是,我在其功能区控件的自定义选项卡中放置了一个按钮,该按钮最初是禁用的。
在我的自定义选项卡中单击其他功能区按钮后,我需要启用最初禁用的按钮。
我试过:
btnCancelar.Visible = true;
在按钮的Click事件中,按钮没有显示。奇怪的是,调试的时候还是没有出现,但是如果出现了MessageBox,按钮终于可以看到了。
我不明白这种行为。如何通过代码动态启用或禁用功能区按钮?
我不确定你的项目使用的是什么语言,但我想你可以将它转换成你自己使用的语言。我将在此处以 C# 显示示例:
首先,您需要在 RibbonXML 定义中实现所谓的回调函数:
<button id="buttonSomething" label="Content" size="large" getVisible="EnableControl"/>
那么下一步就是实现回调函数:
public bool EnableControl(IRibbonControl control)
{
return true; // visible ... false = invisible
}
VSTO 将触发 getVisible 回调并根据 return 值启用或禁用可见状态(不要忘记从 RibbonXML 中删除任何 Visible 属性,否则回调不会触发)
如果是功能区设计器,您需要确保您的点击签名正确,最简单的方法是双击功能区设计器上的按钮。这将为您创建 Click 方法,例如:
我用功能区设计器创建了一个功能区并添加了两个按钮。双击第一个按钮得到一个如下所示的空方法,并添加代码。
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
}
这对我来说非常有效,所以如果它对你不起作用,请提供更多编码细节。
我已经为此创建了一个解决方法。
很简单。刚刚在不同的线程中开始了漫长的 运行 过程。这样,取消按钮会在应该显示的时候显示,然后在进程结束后隐藏。
我使用此代码在 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 是线程安全的,因此在新的 sheet 中添加行或设置 Visible [ 时都没有必要添加同步机制。 =29=]再次为假。
此致
海梅
我为 Excel 开发了一个 VSTO 4 插件。它工作完美,但是,我在其功能区控件的自定义选项卡中放置了一个按钮,该按钮最初是禁用的。
在我的自定义选项卡中单击其他功能区按钮后,我需要启用最初禁用的按钮。
我试过:
btnCancelar.Visible = true;
在按钮的Click事件中,按钮没有显示。奇怪的是,调试的时候还是没有出现,但是如果出现了MessageBox,按钮终于可以看到了。
我不明白这种行为。如何通过代码动态启用或禁用功能区按钮?
我不确定你的项目使用的是什么语言,但我想你可以将它转换成你自己使用的语言。我将在此处以 C# 显示示例:
首先,您需要在 RibbonXML 定义中实现所谓的回调函数:
<button id="buttonSomething" label="Content" size="large" getVisible="EnableControl"/>
那么下一步就是实现回调函数:
public bool EnableControl(IRibbonControl control)
{
return true; // visible ... false = invisible
}
VSTO 将触发 getVisible 回调并根据 return 值启用或禁用可见状态(不要忘记从 RibbonXML 中删除任何 Visible 属性,否则回调不会触发)
如果是功能区设计器,您需要确保您的点击签名正确,最简单的方法是双击功能区设计器上的按钮。这将为您创建 Click 方法,例如:
我用功能区设计器创建了一个功能区并添加了两个按钮。双击第一个按钮得到一个如下所示的空方法,并添加代码。
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
}
这对我来说非常有效,所以如果它对你不起作用,请提供更多编码细节。
我已经为此创建了一个解决方法。
很简单。刚刚在不同的线程中开始了漫长的 运行 过程。这样,取消按钮会在应该显示的时候显示,然后在进程结束后隐藏。
我使用此代码在 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 是线程安全的,因此在新的 sheet 中添加行或设置 Visible [ 时都没有必要添加同步机制。 =29=]再次为假。
此致
海梅