共用方式為


VSPackage 如何新增使用者介面元素

VSPackage 可以透過 .vsct 檔案,將使用者介面 (UI) 元素新增至 Visual Studio,例如:功能表、工具列和工具視窗。

您可以在 Visual Studio 使用者體驗方針中找到 UI 元素的設計指導方針。

Visual Studio 命令表架構

如前所述,命令表架構支援上述架構原則。 命令表架構抽象概念、資料結構和工具背後的原則如下:

  • 有三種基本類型的項目:功能表、命令和群組。 功能表可以在 UI 中公開為功能表、子功能表、工具列或工具視窗。 命令是使用者可以在 IDE 中執行的程序,而且它們可以公開為功能表項目、按鈕、清單方塊或其他控制項。 群組是功能表和命令的容器。

  • 每個項目都由一個定義來指定,該定義描述項目、其相對於其他項目的優先順序以及修改其行為的旗標。

  • 每個專案都有描述項目父系的位置。 項目可以有多個父系,使其可以出現在 UI 中的多個位置。

每個命令都必須有一個群組作為其父系,即使它是該組中唯一的子系。 每個標準功能表也必須有父群組。 工具列和工具視窗會做為自己的父系。 群組可以將主 Visual Studio 功能表列或任何功能表、工具列或工具視窗作為其父系。

如何定義專案

.vsct 檔案的格式為 XML。 它會定義套件的 UI 元素,並決定這些元素在 IDE 中的顯示位置。 套件中的每個功能表、群組或命令都會先在 Symbols 區段中指派 GUID 和識別碼。 在 .vsct 檔案的其餘部分中,每個功能表、命令和群組均由其 GUID 和識別碼組合來識別。 下列範例顯示在範本中選取 [功能表命令] 時,由 Visual Studio 套件範本所產生的典型 Symbols 區段。

<Symbols>
  <!-- This is the package guid. -->
  <GuidSymbol name="guidMenuTextPkg" value="{b1253bc6-d266-402b-89e7-5e3d3b22c746}" />

  <!-- This is the guid used to group the menu commands together -->
  <GuidSymbol name="guidMenuTextCmdSet" value="{a633d4e4-6c65-4436-a138-1abeba7c9a69}">
    <IDSymbol name="MyMenuGroup" value="0x1020" />
    <IDSymbol name="cmdidMyCommand" value="0x0100" />
  </GuidSymbol>

  <GuidSymbol name="guidImages" value="{53323d9a-972d-4671-bb5b-9e418480922f}">
    <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" />
  </GuidSymbol>
</Symbols>

Symbols 區段的最上層元素是 GuidSymbol 元素GuidSymbol 元素會將名稱對應至 IDE 用來識別套件及其元件部分的 GUID。

注意

GUID 由 Visual Studio 套件範本自動產生。 還可以透過按一下 [工具] 功能表上的 [建立 GUID] 來建立唯一的 GUID。

第一個 GuidSymbol 元素 guid<PackageName>Pkg 是套件本身的 GUID。 這是 Visual Studio 用來載入套件的 GUID。 一般而言,它沒有子元素。

依照慣例,功能表和命令會分組在第二個 GuidSymbol 元素 guid<PackageName>CmdSet 之下,而點陣圖則位於第三個 GuidSymbol 元素 guidImages 之下。 您不一定必須遵循此慣例,但每個功能表、群組、命令和點陣圖都必須是 GuidSymbol 元素的子系。

在第二個 GuidSymbol 元素 (代表套件命令集) 中,有幾個 IDSymbol 元素。 每個 IDSymbol 元素都會將名稱對應至數值,而且可能代表屬於命令集一部分的功能表、群組或命令。 第三個 GuidSymbol 元素中的 IDSymbol 元素代表可用來做為命令圖示的點陣圖。 由於 GUID/ID 對在應用程式中必須是唯一的,因此相同 GuidSymbol 元素的兩個子元素不能具有相同的值。

當功能表、群組或命令具有 GUID 和識別碼時,可以將它新增至 IDE。 每個 UI 元素都必須具有以下內容:

  • guid 屬性符合 UI 元素定義下之 GuidSymbol 項目的名稱。

  • 符合相關聯 IDSymbol 項目名稱的 id 屬性。

guidid 屬性會組成UI元素的簽章

  • priority屬性用於確定 UI 元素在其父功能表或群組中的位置。

  • 父元素具有指定父功能表或群組簽署的 guidid 屬性。

每個功能表都會定義為 Menus 區段中的 Menu 元素。 選單必須有 guididpriority 屬性以及 Parent 元素,與下列其他屬性和子系:

  • type 屬性指定功能表應該以某種功能表或工具列的形式出現在 IDE 中。

  • Strings 元素包含 ButtonText 元素 (指定 IDE 中的功能表標題) 和 CommandName 元素 (指定在命令視窗中用於存取功能表的名稱)。

  • 選擇性旗標。 CommandFlag 元素可能會出現在功能表定義中,以變更其在 IDE 中的外觀或行為。

除非它是工具列等可停駐元素,否則每個 Menu 元素都必須有群組作為其父系。 可停駐功能表是它自己的父系。 如需 type 屬性功能表和值的詳細資訊,請參閱 Menu 元素文件。

下面範例顯示出現在 Visual Studio 功能表列上的 [工具] 功能表旁邊的功能表。

<Menu guid="guidTopLevelMenuCmdSet" id="TopLevelMenu" priority="0x700" type="Menu">
  <Parent guid="guidSHLMainMenu" id="IDG_VS_MM_TOOLSADDINS" />
  <Strings>
    <ButtonText>TestMenu</ButtonText>
    <CommandName>TestMenu</CommandName>
  </Strings>
</Menu>

群組

群組是 .vsct 檔案的 Groups 區段中定義的項目。 群組只是容器。 它們不會出現在 IDE 中,除非是做為功能表的分隔線。 因此,Group 元素 只會由其簽章、優先順序和父系定義。

群組可以有一個功能表、另一個群組或本身做為父系。 不過,父系通常是功能表或工具列。 先前範例中的功能表是 IDG_VS_MM_TOOLSADDINS 群組的子系,而該群組是 Visual Studio 功能表列的子系。 下列範例中的群組是先前範例中功能表的子系。

<Group guid="guidTopLevelMenuCmdSet" id="MyMenuGroup" priority="0x0600">
  <Parent guid="guidTopLevelMenuCmdSet" id="TopLevelMenu"/>
</Group>

因為它是功能表的一部分,所以此群組通常會包含命令。 不過,它也可以包含其他功能表。 這就是子功能表的定義方式,如下列範例所示。

<Menu guid="guidTopLevelMenuCmdSet" id="SubMenu" priority="0x0100" type="Menu">
  <Parent guid="guidTopLevelMenuCmdSet" id="MyMenuGroup"/>
  <Strings>
    <ButtonText>Sub Menu</ButtonText>
    <CommandName>Sub Menu</CommandName>
  </Strings>
</Menu>

命令

提供給 IDE 的命令定義為 Button 元素Combo 元素。 若要出現在功能表或工具列上,命令必須有群組做為其父系。

按鈕

按鈕在 Buttons 區段中定義。 使用者按一下以執行單一命令的任何功能表項目、按鈕或其他元素,都會被視為按鈕。 某些按鈕類型也可以包含清單功能。 按鈕具有與功能表相同的必要和可選屬性,而且還可以有一個 Icon 元素,用於指定 IDE 中代表按鈕的點陣圖的 GUID 和識別碼。 如需按鈕及其屬性的詳細資訊,請參閱 Buttons 元素文件。

下列範例中的按鈕是先前範例中群組的子系,而且會在 IDE 中顯示做為該群組之父功能表上的功能表項目。

<Button guid="guidTopLevelMenuCmdSet" id="cmdidTestCommand" priority="0x0100" type="Button">
  <Parent guid="guidTopLevelMenuCmdSet" id="MyMenuGroup" />
  <Icon guid="guidImages" id="bmpPic1" />
  <Strings>
    <CommandName>cmdidTestCommand</CommandName>
    <ButtonText>Test Command</ButtonText>
  </Strings>
</Button>
Combos

Combos 在 Combos 區段中定義。 每個 Combo 元素都代表 IDE 中的下拉式清單方塊。 使用者可以寫入或不可寫入清單方塊,這取決於組合的 type 屬性的值。 Combos 具有與按鈕相同的元素和行為,還可以具有下列其他屬性:

  • 指定像素寬度的 defaultWidth 屬性。

  • idCommandList 屬性用於指定包含清單方塊中顯示項目的清單。 命令清單必須在包含組合的相同 GuidSymbol 節點中宣告。

下面的範例定義一個組合元素。

<Combos>
  <Combo guid="guidFirstToolWinCmdSet"
         id="cmdidWindowsMediaFilename"
         priority="0x0100" type="DynamicCombo"
         idCommandList="cmdidWindowsMediaFilenameGetList"
         defaultWidth="130">
    <Parent guid="guidFirstToolWinCmdSet"
            id="ToolbarGroupID" />
    <CommandFlag>IconAndText</CommandFlag>
    <CommandFlag>CommandWellOnly</CommandFlag>
    <CommandFlag>StretchHorizontally</CommandFlag>
    <Strings>
      <CommandName>Filename</CommandName>
      <ButtonText>Enter a Filename</ButtonText>
    </Strings>
  </Combo>
</Combos>
點陣圖

將與圖示一起顯示的命令必須包含 Icon 元素,該元素透過使用點陣圖的 GUID 和識別碼來引用點陣圖。 每個點陣圖都會定義為 Bitmaps區段中的 Bitmap元素Bitmap 定義所需的唯一屬性是 guidhref (指向來源檔案)。 如果來源檔案是資源區域,也需要 也需要 usedList 屬性才能列出區域中的可用映像。 如需詳細資訊,請參閱 Bitmap 元素文件。

父系

下列規則會控管項目如何呼叫另一個項目做為其父系。

Element 在命令表的本節中定義 可能 (作為父系,或藉由置在 CommandPlacements 區段或兩者兼而有之) 被包含 可能包含 (稱為父系)
群組 Groups 元素、IDE、其他 VSPackage 功能表、群組、項目本身 功能表、群組和命令
功能表 Menus 元素、IDE、其他 VSPackage 1 到 n 個群組 0 到 n 個群組
工具列 Menus 元素、IDE、其他 VSPackage 項目本身 0 到 n 個群組
功能表項目 Buttons 元素、IDE、其他 VSPackage 1 到 n 個群組,項目本身 -0 到 n 個群組
Button Buttons 元素、IDE、其他 VSPackage 1 到 n 個群組,項目本身
組合圖 Combos 元素、IDE、其他 VSPackage 1 到 n 個群組,項目本身

功能表、群組或命令可以出現在 IDE 中的多個位置。 若要讓項目出現在多個位置,必須將其做為 CommandPlacement 元素 新增至 CommandPlacements 部分。 任何功能表、群組或命令都可以新增為命令位置。 不過,工具列無法以這種方式放置,因為它們不能出現在多個內容相關的位置。

命令位置具有 guididpriority 屬性。 GUID 和識別碼必須符合所放置專案的 GUID 和識別碼。 priority 屬性會控管項目與其他項目相關的位置。 當 IDE 合併兩個或多個具有相同優先順序的項目時,它們的位置是未定義的,因為 IDE 不保證每次建置套件時都會以相同的順序讀取套件資源。

如果功能表或群組出現在多個位置,則功能表或群組的所有子系都會出現在每個執行個體中。

命令可見性和內容

安裝多個 VSPackage 時,大量的功能表、功能表項目和工具列可能會讓 IDE 雜亂無章。 為了避免此問題,您可以使用可視性約束和命令旗標來控制各個 UI 元素的可視性。

可視性約束

可視性約束會在 VisibilityConstraints 區段中設定為 VisibilityItem 元素。 可視性約束會定義可視目標項目的特定 UI 內容。 只有在其中一個定義的內容為使用中時,才會顯示本節中包含的功能表或命令。 如果本節中未引用功能表或命令,則預設一律會顯示功能表或命令。 本節不適用於群組。

VisibilityItem 元素必須有三個屬性,如下所示: 目標 UI 項目的 guidid,以及 contextcontext 屬性會指定目標項目何時可見,並採用任何有效的 UI 內容做為其值。 Visual Studio 的 UI 內容常數是 VSConstants 類別的成員。 每個 VisibilityItem 元素只能採用一個內容值。 若要套用第二個內容,請建立指向相同專案的第二個 VisibilityItem 元素,如下列範例所示。

<VisibilityConstraints>
  <VisibilityItem guid="guidSolutionToolbarCmdSet"
        id="cmdidTestCmd"
        context="UICONTEXT_SolutionHasSingleProject" />
  <VisibilityItem guid="guidSolutionToolbarCmdSet"
        id="cmdidTestCmd"
        context="UICONTEXT_SolutionHasMultipleProjects" />
</VisibilityConstraints>

命令旗標

下列命令旗標可能會影響其套用的功能表和命令的可視性。

即使沒有群組或按鈕,也會建立 AlwaysCreate 功能表。

適用於:Menu

CommandWellOnly 如果命令未出現在最上層功能表上,而且您希望讓它可用於其他殼層自訂 (例如:將它繫結至機碼),則套用此旗標。 安裝 VSPackage 之後,使用者可以開啟 [選項] 對話方塊,然後在 [鍵盤環境] 類別下編輯命令位置來自訂這些命令。 不會影響捷徑功能表、工具列、功能表控制器或子功能表的位置。

適用於:ButtonCombo

DefaultDisabled 預設情況下,如果未載入實作命令的 VSPackage 或未呼叫 QueryStatus 方法,則會停用命令。

適用於:ButtonCombo

DefaultInvisible 預設情況下,如果未載入實作命令的 VSPackage 或未呼叫 QueryStatus 方法,則看不見命令。

應該與 DynamicVisibility 旗標結合。

適用於:ButtonComboMenu

DynamicVisibility 可以使用 QueryStatus 方法或 VisibilityConstraints 區段所包含的內容 GUID 來變更命令的可視性。

適用於出現在功能表上而不是工具列上的命令。 當 QueryStatus 方法傳回 OLECMDF_INVISIBLE 旗標時,可以停用最上層工具列項目,但無法隱藏。

在功能表上,此旗標也表示當其成員隱藏時,它應該會自動隱藏。 此旗標通常會指派給子功能表,因為最上層功能表已經具有此行為。

應該與 DefaultInvisible 旗標結合。

適用於:ButtonComboMenu

NoShowOnMenuController 如果具有此旗標的命令位於功能表控制器上,命令就不會出現在下拉式清單中。

適用於:Button

如需命令旗標的詳細資訊,請參閱 CommandFlag 元素文件。

一般需求

您的命令必須先通過以下一系列測試,才能顯示並啟用:

  • 命令已正確定位。

  • 未設定 DefaultInvisible 旗標。

  • 顯示父功能表或工具列。

  • 由於 VisibilityConstraints 元素區段中的內容項目,因此並非看不見命令。

  • 實作 IOleCommandTarget 介面的 VSPackage 程式碼會顯示並啟用您的命令。 沒有介面程式碼攔截它,並對其進行操作。

  • 當使用者按一下您的命令時,它會遵循路由演算法中所述的程序。

呼叫預定義的命令

UsedCommands 元素使 VSPackages 能夠存取其他 VSPackage 或 IDE 提供的命令。 若要這樣做,請建立 UsedCommand 元素,其中具有要使用命令的 GUID 和識別碼。 這可確保命令會由 Visual Studio 載入,即使它不是目前 Visual Studio 組態的一部分也一樣。 如需詳細資訊,請參閱 UsedCommand 元素

介面項目外觀

選取和定位命令元素的考量如下:

  • Visual Studio 提供許多不同的 UI 元素,這些元素根據位置的不同而以不同的方式顯示。

  • 除非使用 DefaultInvisible 旗標定義的 UI 元素是由 QueryStatus 方法的 VSPackage 實作顯示,或與 VisibilityConstraints 區段中特定 UI 內容相關聯,否則不會顯示在IDE中。

  • 即使成功定位的命令也可能不會顯示。 這是因為 IDE 會自動隱藏或顯示某些命令,這取決於 VSPackage 已實作 (或尚未實作) 的介面而定。 例如:VSPackage 的一些組建介面實作會導致自動顯示組建相關的功能表項目。

  • 在 UI 元素的定義中套用 CommandWellOnly 旗標表示只能透過自訂新增命令。

  • 可能只在某些 UI 內容中才能使用命令,例如:只當 IDE 處於設計檢視時才會顯示對話方塊時。

  • 若要讓某些 UI 元素顯示在 IDE 中,您必須實作一或多個介面,或撰寫一些程式碼。