locked
Set Tools menu item to visible only when a Solution is loaded RRS feed

  • Question

  • Hi there,

    I am building a Visual Studio Extension Package with VS 2013.

    I have been following the Menus and Commands Sample from the SDK.

    I can see that at runtime you can set a menu to be visible or not visible, however how do I go about triggering this only when a Solution has been loaded?

    Is there something that I can hook into that lets me know a Solution is loaded? 

    Many thanks in advance

    Monday, March 21, 2016 5:00 AM

Answers

  • The visibility of a menu item, is controlled programmatically via a BeforeQueryStatus handler.

    You will need to create an OleMenuCommand instead of a MenuCommand, and add a BeforeQueryStatus handler that tests to see if a solution is loaded, and if so, set the OleMenuCommand.Visible property accordingly. For example:

            private uint slnExistsContextCookie = 0;

            protected override void Initialize()
            {
                base.Initialize();

                // Add our command handlers for menu (commands must exist in the .vsct file)
                OleMenuCommandService mcs = GetService(typeof(IMenuCommandService)) as OleMenuCommandService;
                if ( null != mcs )
                {
                    // Create the command for the menu item.
                    CommandID menuCommandID = new CommandID(GuidList.guidShowOnlyWhenSolutionLoadedCmdSet, (int)PkgCmdIDList.cmdidMyCommand);
                    OleMenuCommand menuItem = new OleMenuCommand(MenuItemCallback, menuCommandID );
                    mcs.AddCommand( menuItem );
                    menuItem.BeforeQueryStatus += menuItem_BeforeQueryStatus;
                }
            }

            void menuItem_BeforeQueryStatus(object sender, EventArgs e)
            {
                OleMenuCommand menuItem = (OleMenuCommand)sender;
                IVsMonitorSelection vsMonSel = (IVsMonitorSelection)GetService(typeof(SVsShellMonitorSelection));

                if (slnExistsContextCookie==0)
                {
                    // one time initialization
                    Guid slnExistsContextGuid = VSConstants.UICONTEXT.SolutionExistsAndFullyLoaded_guid;
                    vsMonSel.GetCmdUIContextCookie(ref slnExistsContextGuid, out slnExistsContextCookie);
                }

                int active = 0;
                vsMonSel.IsCmdUIContextActive(slnExistsContextCookie, out active);
                menuItem.Visible = active != 0;
            }

    Additionally, as most packages are delay loaded, you will also want control the visibility of your menu item, when the package hasn't loaded yet, where the above handler isn't yet available.

    This is done with a <VisibilityItem> element added to the <VisibilityConstraints> section of your .VSCT file. Then add the DynamicVisibility CommandFlag to the button definition of your item, and you'll be good to go.

    For example:

    <?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="guidShowOnlyWhenSolutionLoadedPkg">
        <Groups>
          <Group guid="guidShowOnlyWhenSolutionLoadedCmdSet" id="MyMenuGroup" priority="0x0600">
            <Parent guid="guidSHLMainMenu" id="IDM_VS_MENU_TOOLS"/>
          </Group>
        </Groups>
       
        <Buttons>
          <Button guid="guidShowOnlyWhenSolutionLoadedCmdSet" id="cmdidMyCommand" priority="0x0100" type="Button">
            <Parent guid="guidShowOnlyWhenSolutionLoadedCmdSet" id="MyMenuGroup" />
            <Icon guid="guidImages" id="bmpPic1" />
            <CommandFlag>DynamicVisibility</CommandFlag>
            <Strings>
              <ButtonText>My Command name</ButtonText>
            </Strings>
          </Button>
        </Buttons>
      
        <Bitmaps>
          <Bitmap guid="guidImages" href="Resources\Images.png" usedList="bmpPic1, bmpPic2, bmpPicSearch, bmpPicX, bmpPicArrows"/>
        </Bitmaps>
      </Commands>

      <VisibilityConstraints>
        <VisibilityItem guid="guidShowOnlyWhenSolutionLoadedCmdSet" id="cmdidMyCommand" context="UICONTEXT_SolutionExists"/>
      </VisibilityConstraints>

      <Symbols>
        <GuidSymbol name="guidShowOnlyWhenSolutionLoadedPkg" value="{1a622259-8c65-4813-b84d-00c4aeb78eaa}" />
        <GuidSymbol name="guidShowOnlyWhenSolutionLoadedCmdSet" value="{de54ada2-27d3-4d56-a0fc-50c69d71b2f8}">
          <IDSymbol name="MyMenuGroup" value="0x1020" />
          <IDSymbol name="cmdidMyCommand" value="0x0100" />
        </GuidSymbol>
        <GuidSymbol name="guidImages" value="{91d2586d-6f0f-4f73-a069-299c7d0195b9}" >
          <IDSymbol name="bmpPic1" value="1" />
          <IDSymbol name="bmpPic2" value="2" />
          <IDSymbol name="bmpPicSearch" value="3" />
          <IDSymbol name="bmpPicX" value="4" />
          <IDSymbol name="bmpPicArrows" value="5" />
          <IDSymbol name="bmpPicStrikethrough" value="6" />
        </GuidSymbol>
      </Symbols>
    </CommandTable>

    Sincerely,


    Ed Dore

    Wednesday, March 23, 2016 8:23 PM