How to: Dynamically Add Menu Items By Using DYNAMICITEMSTART

注意

Beginning with Visual Studio 2008 SDK, use XML Command Table (.vsct) files instead of command table configuration (.ctc) files to define how menus and commands appear in your VSPackages. For more information, see XML-Based Command Table Configuration (.vsct) Files.

A command that is defined in the Command Table Configuration (.Ctc) Files and is marked with the DynamicItemStart flag specifies a position on a menu where dynamically created commands are inserted. Dynamic commands are typically created when the associated VSPackage is started and can be updated when the VSPackage is open.

Two common kinds of dynamic lists are as follows:

  • Most Recently Used (MRU) list, which typically displays the names of documents that have been opened recently.

  • Windows list, which typically displays the names of windows that are currently open.

The DynamicItemStart flag on a command definition specifies that the command is a placeholder until the VSPackage is opened. When the VSPackage is opened, the placeholder is replaced with 0 or more commands that are created at run time by the VSPackage and added to the dynamic list. You may not be able to see the position on the menu where the dynamic list appears until the VSPackage is opened.

To populate the dynamic list, the integrated development environment (IDE) first calls the VSPackage to look for a command that has an ID whose first characters are the same as the ID of the placeholder. When the IDE finds a matching command, it adds the name of the command to the dynamic list. Then the IDE increments the ID and looks for another matching command to add to the dynamic list. The IDE continues to increment the ID and add to the dynamic list until there are no more dynamic commands.

The first procedure describes how to create a dynamic MRU list in a submenu.

The second procedure describes how to populate a dynamic list by using the Managed Package Framework (MPF).

注意

The Walkthrough: Creating an MRU Menu List walkthrough shows how to create an MRU list in both managed (Visual C#) and unmanaged (Visual C++) code.

To create a dynamic command list

  1. Create a new submenu and its command group as described in How to: Create Cascading Submenus.

    This submenu will contain the dynamic list. Add DefaultInvisible | DynamicVisibility to your submenu definition so the parent menu can be hidden automatically if desired.

  2. Create a command in the BUTTONS_BEGIN – BUTTONS_END section of your .ctc file. This will be the dynamic list placeholder.

    1. Set the Command ID field to the GUID:ID pair that represents the placeholder. This GUID:ID pair is the first in a list of dynamic commands that are later added by the VSPackage. Each subsequent dynamic command has an ID that is one greater than the ID of the previous dynamic command.

    2. Set the Group ID to the GUID:ID pair of the group that was created for the submenu in step 1.

    3. Set the Priority field to 0.

      This particular submenu contains only the single dynamic list. Therefore, the priority of the first item does not matter. Dynamic items added later have the same priority; the order in which each is added dictates its relative position.

    4. Set the Icon ID field to guidOfficeIcon:msotcidNoIcon.

      A dynamic command cannot have an icon associated with it. Therefore, the Icon ID field must be set to indicate that no icon is to be used.

    5. Set the Button Type file to Button.

      A dynamic command has the type Button just like any other command.

    6. Set the Flags field to DynamicItemStart.

      This marks the command as a placeholder.

      注意

      All other flags are ignored! If you want to control the visibility of a dynamic item, you must do so from the VSPackage at run time.

    7. Set the Button Text field to the name of the placeholder.

      Typically, this button text is not seen if the VSPackage can initialize the dynamic list before the menu that contains it is shown.

  3. Use the Command Table Compiler (Ctc.exe) to convert your .ctc file to a binary resource that can be included in your VSPackage satellite .dll file. For information about the Command Table Compiler, see How to: Create Menu Commands for a VSPackage By Using the Binary Command Table Compiler.

To implement a dynamic list in the MPF

  • The MPF uses event handlers to hide the details of the IOleCommandTarget interface and its QueryStatus method. For a VSPackage written by using the MPF to support a dynamic list of menu commands, create a list of OleMenuCommand objects to represent each item in the dynamic list. Each OleMenuCommand object has the same event handlers for executing the command and for getting the status of the command. For example:

    using Microsoft.VisualStudio.Shell;
    
    //////////////////////////////////////////////////////////////////
    // Initialize the dynamic list.
    private void CreateMRUList(OleMenuCommandService mcs, int numItems)
    {
        int baseCommandID = PkCmdList.cmdidPlaceHolder;
    
        for (int i = 0; i < numItems; i++)
        {
            CommandID cmdID = new CommandID(GuidList.MyCommandSet,
                                            baseCommandID + i);
            OleMenuCommand dynamicCmd;
            dynamicCmd = new OleMenuCommand(new EventHandler(this.OnMRUExec),
                                            cmdID);
            dynamicCmd.BeforeQueryStatus += new EventHandler(this.OnMRUQueryStatus);
            mcs.AddCommand(dynamicCmd);
        }
    
        // This adds the MRU menu itself as a command so it is possible
        // to control the visibility of the menu dynamically while the
        // VSPackage is running.
        CommandID menuCmdID = new CommandID(GuidList.MyCommandSet,
                                            PkgCmdList.MyMRUMenu);
        OleMenuCommand menuCmd = new OleMenuCommand(null, menuCmdID);
        menuCmd.BeforeQueryStatus += new EventHandler(this.OnMRUMenuQueryStatus);
        mcs.AddCommand(menuCmd);
    }
    
    //////////////////////////////////////////////////////////////////
    // Handle a click on a dynamic item.
    private void OnMRUExec(object sender, EventArgs e)
    {
        OleMenuCommand menuCmd = sender as menuCmd;
        if (null != menuCmd)
        {
            int selectedID = menuCmd.CommandID.ID - PkgCmdList.cmdidPlaceHolder;
            // selectedID represents the relative index of the selected item.
        }
    }
    
    
    //////////////////////////////////////////////////////////////////
    // Handle updating the text and status of a dynamic item.
    private void OnMRUQueryStatus(object sender, EventArgs e)
    {
        OleMenuCommand menuCmd = sender as menuCmd;
        if (null != menuCmd)
        {
            int selectedID = menuCmd.CommandID.ID - PkgCmdList.cmdidPlaceHolder;
            // selectedID represents the relative index of the selected item.
            // Set menuCmd.Text to the text that is to appear for this item.
            // Set menuCmd.Visible to true or false depending on whether the item is visible.
        }
    }
    
    
    //////////////////////////////////////////////////////////////////
    // Handle updating the visibility of the MRU menu itself.
    private void OnMRUMenuQueryStatus(object sender, EventArgs e)
    {
        OleMenuCommand menuCmd = sender as menuCmd;
        if (null != menuCmd)
        {
            // Set menuCmd.Visible to true or false depending on whether
            // the MRU list should even be seen.
        }
    }
    

See Also

Concepts

Dynamic Menu

Menus and Toolbars

How VSPackages Add User Interface Elements

Common Menu Tasks