假设我们在工具栏上有一个带工具栏和几个命令的VSPackage。 如何以编程方式显示/隐藏工具栏上的某个命令?如果您是用户,则可以通过自定义工具栏来执行此操作。因此,我强烈认为必须有一种方法可以从代码中做到这一点。
由于我们没有开发AddIn,我们无法使用
DTE.Commands.AddNamedCommand(AddInInstance, Name, ButtonText, ToolTip, MSOButton)
。
没关系,因为我们仍然可以使用 Visual Studio命令表(.vsct)格式定义命令,这是VSPackages的建议方式:
<?xml version="1.0" encoding="utf-8"?>
<CommandTable xmlns="http://schemas.microsoft.com/VisualStudio/2005-10-18/CommandTable" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<Extern href="vsshlids.h" />
<Commands package="testPackage">
<Menus> <!-- Define the menus, toolbars, etc. -->
<Menu guid="commands" id="toolbar" type="Toolbar">
<Parent guid="guidSHLMainMenu" id="IDG_VS_BUILD_SOLUTION" />
<CommandFlag>DefaultDocked</CommandFlag>
<Strings>
<ButtonText>TestToolbar</ButtonText>
</Strings>
</Menu>
</Menus>
<Groups> <!-- Define the groups for commands -->
<Group guid="commands" id="toolbarGroup" priority="0x0001">
<Parent guid="commands" id="toolbar" />
</Group>
</Groups>
<Buttons> <!-- Define the commands as buttons -->
<Button guid="commands" id="button0" type="Button">
<Parent guid="commands" id="toolbarGroup" />
<CommandFlag>DynamicVisibility</CommandFlag>
<Strings>
<ButtonText>TestButton0</ButtonText>
</Strings>
</Button>
<Button guid="commands" id="button1" type="Button">
<Parent guid="commands" id="toolbarGroup" />
<CommandFlag>DynamicVisibility</CommandFlag>
<Strings>
<ButtonText>TestButton1</ButtonText>
</Strings>
</Button>
</Buttons>
</Commands>
<Symbols>
<GuidSymbol name="testPackage" value="{FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF}" />
<GuidSymbol name="commands" value="{EEEEEEEE-EEEE-EEEE-EEEE-EEEEEEEEEEEE}">
<IDSymbol name="toolbar" value="0x0100" />
<IDSymbol name="toolbarGroup" value="0x0010" />
<IDSymbol name="button0" value="0x0000" />
<IDSymbol name="button1" value="0x0001" />
</GuidSymbol>
</Symbols>
</CommandTable>
稍后在C#代码中,您可以设置我们刚刚定义的MenuCommand的不同属性:
System.ComponentModel.Design.MenuCommand menuCommand = <Acquire your menu command>;
menuCommand.Enabled = <enabled>;
menuCommand.Visible = <visible>;
menuCommand.Supported = <supported>;
问题是,如果将菜单命令放在工具栏上,那么将Visible属性设为false将不会隐藏按钮,只会使其变灰。 (它可以隐藏在任何其他菜单上。)这是Visual Studio的一个功能,而不是错误。
然而,我需要的是:隐藏 Button0 。 (假设 Button0 仅在某些特殊条件适用时显示,例如:您的硬盘驱动器空间少于X MB或安装了其他工具,或者只是在这里自行构成条件。)
如果不需要,可以使用AddIn时间中的以下技术删除按钮:
EnvDTE.Command button0 = DTE.Commands.Item(commandsGuid, button0CommandId); // Both are the same as in the .vsct file
if (button0 != null)
button0.Delete();
找到了Command0 ,但在尝试删除时,我遇到了异常:未指定错误(HRESULT异常:0x80004005(E_FAIL))毕竟,它有点意义,因为它是通过.vsct机制创建的,而不是以编程方式创建的。
我的想法已经不多了。请帮助我了解如何在运行时以编程方式隐藏/显示或添加/删除工具栏按钮。有没有其他方法来定义VSPackage命令但是.vsct文件?
任何帮助表示感谢。
答案 0 :(得分:7)
首先,您必须在vsct文件中的按钮上设置DynamicVisibility标志:
<Button guid="commands" id="button0" priority="0x1001" type="Button">
<Parent guid="commands" id="toolbarGroup" />
<CommandFlag>DefaultInvisible</CommandFlag>
<CommandFlag>DynamicVisibility</CommandFlag>
<Strings>
<ButtonText>TestButton1</ButtonText>
</Strings>
</Button>
接下来,在使用OleMenuCommand类而不是MenuCommand覆盖Package.Initialize create命令处理程序并订阅BeforeQueryStatus事件,如下所示:
OleMenuCommandService mcs = GetService(typeof(IMenuCommandService)) as OleMenuCommandService;
if (null != mcs)
{
// Create the command for the menu item.
CommandID menuCommandID = new CommandID(GuidList.guidToolbarCmdSet, (int)PkgCmdIDList.cmdidButton0);
var menuItem = new OleMenuCommand(MenuItemCallback, menuCommandID);
menuItem.BeforeQueryStatus += BeforeQueryStatusCallback;
mcs.AddCommand(menuItem);
}
现在在BeforeQueryStatusCallback中,您可以显示或隐藏按钮
private void BeforeQueryStatusCallback(object sender, EventArgs e)
{
var cmd = (OleMenuCommand)sender
cmd.Visible = true;
}