我已经为 Excel VSTO 项目编写了 Ribbon.xml 文件。选项卡元素如下所示:
<tab id="myId" idMso="TabAddIns" label="My Tab" visible="false">
当工作簿打开时,我希望选项卡默认隐藏,这是通过将 visible 属性设置为 false 来实现的。接下来,我想在 Workbook_Open 事件中将可见属性更改为 true。这就是我被困的地方。我不认为这会很难,但我花了几个小时在谷歌上搜索答案。似乎大多数示例 1) 通过 button callback 切换选项卡的可见性,这不是我想要做的,或者 2) 能够访问 ribbon's properties ,到目前为止我还无法复制(尽管这些资源中的大部分都是旧的,所以我认为 MS 从那时起就移动了这些属性)。
有谁知道如何轻松地将 visible 属性更改为 true 以便显示选项卡?
谢谢!
更新了更多信息:
ThisAddIn.cs
namespace Doodles_Reporting
{
public partial class ThisAddIn
{
public RibbonApi ribbonApi;
private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
}
private void ThisAddIn_Shutdown(object sender, System.EventArgs e)
{
}
protected override Microsoft.Office.Core.IRibbonExtensibility CreateRibbonExtensibilityObject()
{
return new Ribbon();
}
void Application_WorkbookOpen(Excel.Workbook Wb)
{
//first, check if there is an application/process for each workbook
Excel.Workbooks books = Globals.ThisAddIn.Application.Workbooks;
if (books.Count > 1)
{
try
{
//close workbook that was just opened and then reopen it with new process/application.
string filePath = Wb.FullName;
Wb.Close();
Excel.Application excelApp = new Excel.Application();
excelApp.Visible = true;
excelApp.DisplayFullScreen = true;
excelApp.Workbooks.Open(filePath);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK);
}
}
else
{
//second, check if the workbook is a Doodles workbook
try
{
DocumentProperties props = (DocumentProperties)Wb.CustomDocumentProperties;
var selectedTable = props["selectedTable"].Value;
configureDoodles();
}
catch (Exception)
{
//THIS IS WHERE I WANT TO SET THE RIBBON VISIBILITY TO FALSE
}
}
}
private void configureDoodles()
{
RibbonApi.app = Globals.ThisAddIn.Application;
RibbonApi.wBookPropertiesConfig = new WorkbookPropertiesConfig(RibbonApi.app.ActiveWorkbook);
RibbonApi.presenter = new ExcelPresenter(RibbonApi.app.ActiveWorkbook);
ribbonApi = new RibbonApi();
}
#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);
this.Application.WorkbookOpen += new Excel.AppEvents_WorkbookOpenEventHandler(Application_WorkbookOpen);
}
#endregion
}
}
丝带.cs
namespace Doodles_Reporting
{
[ComVisible(true)]
public class Ribbon : Office.IRibbonExtensibility
{
private Office.IRibbonUI ribbon;
public Ribbon()
{
}
#region IRibbonExtensibility Members
public string GetCustomUI(string ribbonID)
{
return GetResourceText("Doodles_Reporting.Ribbon.xml");
}
#endregion
#region Ribbon Callbacks
//Create callback methods here. For more information about adding callback methods, visit http://go.microsoft.com/fwlink/?LinkID=271226
public void Ribbon_Load(Office.IRibbonUI ribbonUI)
{
this.ribbon = ribbonUI;
}
public bool toggleVisibility(Office.IRibbonControl control)
{
return (control.Id == "TabAddIns") ? true : false;
}
public void onSomeEvent()
{
this.ribbon.InvalidateControl("TabAddIns");
}
public void SignIn(Office.IRibbonControl ribbonUI)
{
Globals.ThisAddIn.ribbonApi.signIn();
}
public void SqlCreatorFormLoad(Office.IRibbonControl ribbonUI)
{
Globals.ThisAddIn.ribbonApi.showSqlCreator();
}
public void refreshData(Office.IRibbonControl ribbonUI)
{
Globals.ThisAddIn.ribbonApi.refreshData();
}
public void drilldownSelectionLoad(Office.IRibbonControl ribbonUI)
{
Globals.ThisAddIn.ribbonApi.setDrilldownColumns();
}
public void Drilldown(Office.IRibbonControl ribbonUI)
{
Globals.ThisAddIn.ribbonApi.drilldown();
}
public void editProperties(Office.IRibbonControl ribbonUI)
{
}
#endregion
#region Helpers
private static string GetResourceText(string resourceName)
{
Assembly asm = Assembly.GetExecutingAssembly();
string[] resourceNames = asm.GetManifestResourceNames();
for (int i = 0; i < resourceNames.Length; ++i)
{
if (string.Compare(resourceName, resourceNames[i], StringComparison.OrdinalIgnoreCase) == 0)
{
using (StreamReader resourceReader = new StreamReader(asm.GetManifestResourceStream(resourceNames[i])))
{
if (resourceReader != null)
{
return resourceReader.ReadToEnd();
}
}
}
}
return null;
}
#endregion
}
}
最佳答案
丝带是一只有趣的野兽。它专门设计用于禁止您直接访问其任何元素并禁止您直接操作它们。相反,一切都是通过回调完成的。我没有太多使用 VSTO 的经验,但我可以解释你在没有 VSTO 的情况下用 C# 或 C++ 做什么,我相信你可以填补空白。
在您的功能区 XML 中设置一个
onLoad
回调。首次加载功能区时,Excel 将调用此方法(通过IDispatch
)。<customUI ... onLoad="OnRibbonLoaded">
实现您的
onLoad
回调,它应该存储所提供的IRibbonUI
引用。public void OnRibbonLoaded(IRibbonUI ribbon) { this.ribbon = ribbon; }
对于要动态控制的属性,在功能区 XML 中定义回调。
<tab ... getVisible="GetVisible">
实现可见性回调。如果功能区的多个部分使用相同的回调,则传入此方法的
IRibbonControl
实例可用于确定正在查询哪个选项卡/组/控件。public bool GetVisible(IRibbonControl control) { // here is where you should determine if your tab/group/control should be visible, return (some condition) ? true : false; }
每当您决定要更新可见性时,请使用
IRibbonUI
引用告诉 Excel 重新查询您的控件的属性(即调用您的回调)。void OnSomeEvent() { // you can tell Excel to update the entire ribbon this.ribbon.Invalidate(); // or you can tell Excel to update a single tab/group/control this.ribbon.InvalidateControl("my_id"); }
关于c# - 通过 Workbook_Open 事件更改 VSTO 选项卡的可见属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44789975/