將最近使用的清單新增至子功能表

本逐步解說是以將子功能表新增至功能表的示範為基礎,並說明如何將動態清單新增至子功能表。 動態清單構成建立最近使用 (MRU) 清單的基礎。

動態功能表清單會從功能表上的預留位置開始。 每次顯示功能表時,Visual Studio 整合式開發環境 (IDE) 都會向 VSPackage 詢問應該顯示在預留位置上的所有命令。 動態清單可以發生在功能表上的任何位置。 不過,動態清單通常會自行儲存和顯示在子功能表上或功能表底部。 藉由使用這些設計模式,您可以使命令的動態清單展開和收縮,而不會影響功能表上其他命令的位置。 在本逐步解說中,動態 MRU 清單會顯示在現有子功能表的底部,並以一條線分隔其餘子功能表。

技術上來說,動態清單也可以套用至工具列。 不過,我們不建議這種使用方式,因為除非使用者採取特定步驟來變更工具列,否則工具列應該維持不變。

本逐步解說會建立四個項目的 MRU 清單,以便在每次選取其中一個項目時變更其順序 (選取的項目移至清單頂端)。

如需功能表和 .vsct 檔案的詳細資訊,請參閱命令、功能表和工具列

必要條件

若要依照本逐步解說執行作業,您必須安裝 Visual Studio SDK。 如需詳細資訊,請參閱 Visual Studio SDK

建立延伸模組

建立動態項目清單命令

  1. 開啟 TestCommandPackage.vsct

  2. Symbols 區段中名為 guidTestCommandPackageCmdSet 的 GuidSymbol 節點中,新增 MRUListGroup 群組和 cmdidMRUList 命令的符號,如下所示。

    <IDSymbol name="MRUListGroup" value="0x1200"/>
    <IDSymbol name="cmdidMRUList" value="0x0200"/>
    
  3. Groups 區段中,於現有的群組項目之後新增宣告的群組。

    <Group guid="guidTestCommandPackageCmdSet" id="MRUListGroup"
            priority="0x0100">
        <Parent guid="guidTestCommandPackageCmdSet" id="SubMenu"/>
    </Group>
    
  4. Buttons 區段中,於現有的按鈕項目之後新增節點來代表新宣告的命令。

    <Button guid="guidTestCommandPackageCmdSet" id="cmdidMRUList"
        type="Button" priority="0x0100">
        <Parent guid="guidTestCommandPackageCmdSet" id="MRUListGroup" />
        <CommandFlag>DynamicItemStart</CommandFlag>
        <Strings>
            <CommandName>cmdidMRUList</CommandName>
            <ButtonText>MRU Placeholder</ButtonText>
        </Strings>
    </Button>
    

    DynamicItemStart 旗標可使命令以動態的方式產生。

  5. 建置專案並開始偵錯,以測試新命令的顯示。

    在 [TestMenu] 功能表上,按一下新的子功能表 [子功能表],以顯示新命令 [MRU 預留位置]。 在下一個程序中實作命令的動態 MRU 清單之後,每次開啟子功能表時,這個命令標籤就會由該清單取代。

填滿 MRU 清單

  1. 在 TestCommandPackageGuids.cs 中,於 TestCommandPackageGuids 類別定義中的現有命令識別碼後面新增下列幾行。

    public const string guidTestCommandPackageCmdSet = "00000000-0000-0000-0000-00000000"; // get the GUID from the .vsct file
    public const uint cmdidMRUList = 0x200;
    
  2. 在 TestCommand.cs 中,新增下列 using 陳述式。

    using System.Collections;
    
  3. 在最後一次 AddCommand 呼叫之後,於 TestCommand 建構函式中新增下列程式碼。 InitMRUMenu 將在稍後定義。

    this.InitMRUMenu(commandService);
    
  4. 在 TestCommand 類別中新增以下程式碼。 此程式碼會初始化字串清單,該些字串代表要顯示在 MRU 清單上的項目。

    private int numMRUItems = 4;
    private int baseMRUID = (int)TestCommandPackageGuids.cmdidMRUList;
    private ArrayList mruList;
    
    private void InitializeMRUList()
    {
        if (null == this.mruList)
        {
            this.mruList = new ArrayList();
            if (null != this.mruList)
            {
                for (int i = 0; i < this.numMRUItems; i++)
                {
                    this.mruList.Add(string.Format(CultureInfo.CurrentCulture,
                        "Item {0}", i + 1));
                }
            }
        }
    }
    
  5. InitializeMRUList 方法之後新增 InitMRUMenu 方法。 這會初始化 MRU 清單功能表命令。

    private void InitMRUMenu(OleMenuCommandService mcs)
    {
        InitializeMRUList();
        for (int i = 0; i < this.numMRUItems; i++)
        {
            var cmdID = new CommandID(
                new Guid(TestCommandPackageGuids.guidTestCommandPackageCmdSet), this.baseMRUID + i);
            var mc = new OleMenuCommand(
                new EventHandler(OnMRUExec), cmdID);
            mc.BeforeQueryStatus += new EventHandler(OnMRUQueryStatus);
            mcs.AddCommand(mc);
        }
    }
    

    您必須為 MRU 清單中每個可能的項目建立功能表命令物件。 IDE 會針對 MRU 清單中的每個項目呼叫 OnMRUQueryStatus 方法,直到沒有其他項目為止。 在受控碼中,IDE 知道沒有更多項目的唯一方法是先建立所有可能的項目。 如果您要的話,可以在建立功能表命令之後,先使用 mc.Visible = false; 將其他項目標示為不可見。 然後,在 OnMRUQueryStatus 方法中使用 mc.Visible = true;,即可在稍後顯示這些專案。

  6. InitMRUMenu 方法之後新增下列 OnMRUQueryStatus 方法。 這是為每個 MRU 項目設定文字的處理常式。

    private void OnMRUQueryStatus(object sender, EventArgs e)
    {
        OleMenuCommand menuCommand = sender as OleMenuCommand;
        if (null != menuCommand)
        {
            int MRUItemIndex = menuCommand.CommandID.ID - this.baseMRUID;
            if (MRUItemIndex >= 0 && MRUItemIndex < this.mruList.Count)
            {
                menuCommand.Text = this.mruList[MRUItemIndex] as string;
            }
        }
    }
    
  7. OnMRUQueryStatus 方法之後新增下列 OnMRUExec 方法。 這是選取 MRU 項目的處理常式。 這個方法會將選取的項目移至清單頂端,然後在訊息方塊中顯示選取的項目。

    private void OnMRUExec(object sender, EventArgs e)
    {
        var menuCommand = sender as OleMenuCommand;
        if (null != menuCommand)
        {
            int MRUItemIndex = menuCommand.CommandID.ID - this.baseMRUID;
            if (MRUItemIndex >= 0 && MRUItemIndex < this.mruList.Count)
            {
                string selection = this.mruList[MRUItemIndex] as string;
                for (int i = MRUItemIndex; i > 0; i--)
                {
                    this.mruList[i] = this.mruList[i - 1];
                }
                this.mruList[0] = selection;
                System.Windows.Forms.MessageBox.Show(
                    string.Format(CultureInfo.CurrentCulture,
                                  "Selected {0}", selection));
            }
        }
    }
    

測試 MRU 清單

  1. 建置此專案並開始偵錯。

  2. 在 [TestMenu] 功能表上,按一下 [叫用 TestCommand]。 如此會顯示訊息方塊,指出已選取命令。

    注意

    必須進行此步驟,才能強制 VSPackage 載入並正確顯示 MRU 清單。 如果略過此步驟,便不會顯示 MRU 清單。

  3. 在 [測試功能表] 功能表上,按一下 [子功能表]。 在分隔符號下方的子功能表結尾會顯示四個項目的清單。 當您按一下 [項目 3] 時,應該會出現訊息方塊,並顯示文字「已選取項目 3」。 (如果未顯示四個項目的清單,請確定您已遵循先前步驟中的指示。)

  4. 再次開啟子功能表。 請注意,[項目 3] 現在位於清單頂端,而其他項目已下推一個位置。 再按一次 [項目 3],並注意到訊息方塊仍然顯示 [已選取項目 3],這表示文字與命令標籤已一同正確地移至新位置。