我正在尝试在VS 2015扩展中创建动态菜单项.我能做的最好的事情是让占位符命令可见并处于活动状态.这是我可以从VS向导开始创建的最小的示例(对不起长度,但它确实是我可以创建的最小的示例):
Command1Package.cs:
using Microsoft.VisualStudio; using Microsoft.VisualStudio.Shell; using System; using System.ComponentModel.Design; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Runtime.InteropServices; namespace minimal { [PackageRegistration(UseManagedResourcesOnly = true)] [InstalledProductRegistration("#110","#112","1.0",IconResourceID = 400)] // Info on this package for Help/About [ProvideMenuResource("Menus.ctmenu",1)] [Guid(Command1Package.PackageGuidString)] [ProvideAutoLoad(VSConstants.UICONTEXT.NoSolution_string)] [SuppressMessage("Stylecop.CSharp.DocumentationRules","SA1650:ElementDocumentationMustBeSpelledCorrectly",Justification = "pkgdef,VS and vsixmanifest are valid VS terms")] public sealed class Command1Package : Package { public const string PackageGuidString = "3e88287b-7b79-403d-ae8d-3329af218869"; public Command1Package() { } #region Package Members protected override void Initialize() { Debug.WriteLine("minimal package instantiated"); Command1.Initialize(this,GetService(typeof(IMenuCommandService)) as OleMenuCommandService); base.Initialize(); } #endregion } }
Command1.cs:
using Microsoft.VisualStudio.Shell; using System; using System.ComponentModel.Design; using System.Diagnostics; namespace minimal { internal sealed class Command1 { public static readonly Guid CommandSet = new Guid("c1388361-6429-452c-8ba0-580d292ef0ca"); private Command1() { } public static void Initialize(Package package,OleMenuCommandService mcs) { AddOneCommand(mcs,0x0100,"Renamed placeholder command"); // the placeholder AddOneCommand(mcs,0x0101,"Dynamic command 1"); // a dynamic command AddOneCommand(mcs,0x0102,"Dynamic command 2"); } internal static void AddOneCommand(OleMenuCommandService mcs,uint cmdid,string cmdname) { Debug.WriteLine("AddOneCommand" + cmdid.ToString("X4")); CommandID id = new CommandID(CommandSet,(int) cmdid); OleMenuCommand mc = new OleMenuCommand(new EventHandler(MenuItemCallback),id,cmdname); mc.BeforeQueryStatus += OnBeforeQueryStatus; mcs.AddCommand(mc); } private static void OnBeforeQueryStatus(object sender,EventArgs e) { OleMenuCommand mc = sender as OleMenuCommand; Debug.WriteLine("OnBeforeQueryStatus called for " + mc.CommandID.ToString()); } private static void MenuItemCallback(object sender,EventArgs e) { OleMenuCommand mc = sender as OleMenuCommand; System.Windows.Forms.MessageBox.Show("MenuItemCallback called for " + mc.CommandID.ToString()); } } }
Command1Package.vsct:
<?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="stdidcmd.h"/> <Extern href="vsshlids.h"/> <Commands package="guidCommand1Package"> <Groups> <Group guid="guidCommand1PackageCmdset" id="MyMenuGroup" priority="0x0600"> <Parent guid="guidSHLMainMenu" id="IDM_VS_MENU_TOOLS"/> </Group> <Group guid="guidCommand1PackageCmdset" id="MyMenuSubgroup" priority="0x0100"> <Parent guid="guidCommand1PackageCmdset" id="SubMenu"/> </Group> </Groups> <Menus> <Menu guid="guidCommand1PackageCmdset" id="SubMenu" priority="0x0100" type="Menu"> <Parent guid="guidCommand1PackageCmdset" id="MyMenuGroup"/> <Strings> <ButtonText>Minimal commands</ButtonText> <CommandName>MinimalCommands</CommandName> </Strings> </Menu> </Menus> <Buttons> <Button guid="guidCommand1PackageCmdset" id="Command1Id" priority="0x0100" type="Button"> <Parent guid="guidCommand1PackageCmdset" id="MyMenuSubgroup" /> <CommandFlag>DynamicItemStart</CommandFlag> <CommandFlag>TextChanges</CommandFlag> <CommandFlag>DynamicVisibility</CommandFlag> <Strings> <ButtonText>Invoke Command1</ButtonText> <CommandName>Command1</CommandName> </Strings> </Button> </Buttons> </Commands> <Symbols> <GuidSymbol name="guidCommand1Package" value="{3e88287b-7b79-403d-ae8d-3329af218869}" /> <GuidSymbol name="guidCommand1PackageCmdset" value="{c1388361-6429-452c-8ba0-580d292ef0ca}"> <IDSymbol name="MyMenuGroup" value="0x1020" /> <IDSymbol name="MyMenuSubgroup" value="0x1021"/> <IDSymbol name="SubMenu" value="0x200"/> <IDSymbol name="Command1Id" value="0x0100" /> </GuidSymbol> </Symbols> </CommandTable>
一些观察:
>如果包中没有[ProvideAutoLoad]属性,则在执行占位符命令之前,框架不会实例化包,该命令是该子菜单上唯一的项目.似乎VS向导生成的代码应该为您执行此操作,因为在Package类的帮助条目中未提及此属性(以及许多其他属性).
>我真的希望占位符不会出现在菜单上.但是将其标记为不可见(在OnBeforeQueryStatus中)会使整个子菜单消失.我能做的最好的事情是更改此命令的名称. “如何:动态添加菜单项”的帮助条目没有提到这一点. (不要费心阅读VS 2015的条目,因为示例代码是不必要的复杂,并没有显示如何动态添加菜单命令这一简单的事情.VS 2012示例更容易遵循.)
>< rant> Dang,但这在MFC中更容易! GetMenu(),GetSubMenu()等我认为.net应该比传统的Win32编程更容易.< / rant>
>有没有更好的方法将动态项添加到菜单?
解决方法
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。