2015-09-15 49 views
4

我正嘗試在VS 2015擴展中創建動態菜單項。我能做的最好的方法是讓佔位符命令可見並且處於活動狀態。這裏有最起碼的例子我可以創建開始與VS奇才(遺憾的長度,但它確實是最起碼的例子我可以創建):VS 2015動態菜單命令不能像廣告中那樣工作

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> 

一些觀察:

  1. 沒有在包裝上[ProvideAutoLoad]屬性,框架不會實例直到後你執行的佔位符命令,該命令是在子菜單中的唯一項目包那一點。看起來由VS嚮導生成的代碼應該爲你做這件事,因爲這個屬性(在許多其他中)沒有在Package類的幫助條目中提到。
  2. 我真的希望佔位符不要出現在菜單上。但將其標記爲隱形(在OnBeforeQueryStatus中)使整個子菜單消失。我能做的最好的就是改變這個命令的名字。 「如何:動態添加菜單項」的幫助條目沒有提到這一點。 (不要爲讀取VS 2015的條目而煩心,因爲示例代碼不必要的複雜,並且不會顯示如何動態添加菜單命令。VS 2012示例更容易遵循。)
  3. <rant>當然,但這在MFC中更容易! GetMenu(),GetSubMenu()等。我認爲.net應該比傳統的Win32編程更容易。 </rant >
  4. 有沒有更好的方法來添加動態項目菜單?

回答

0

是的,它比MFC更難。

  1. [ProvideAutoLoad]確實是必需的。

  2. 您不應該添加佔位符命令。從

    AddOneCommand(mcs,0x0100,「Dynamic command 1」);

通常你添加< CommandFlag> DefaultInvisible </CommandFlag>到DynamicItemStart命令,並設置menuCommand。 文本和menuCommand。 在OnBeforeQueryStatus處理程序中可見

相關問題