图像服务和目录

本指南包含采用 Visual Studio 2015 中引入的 Visual Studio 图像服务和图像目录的指南和最佳做法。

Visual Studio 2015 中引入的图像服务使开发人员能够获取适合设备的最佳图像以及用户选择的显示图像的主题,包括针对显示图像的上下文的正确主题。 采用图像服务将有助于消除与资产维护、HDPI 缩放和主题相关的主要痛点。

今天的问题 解决方案
背景色混合 内置 alpha 值混合处理
主题化(一些)图像 主题元数据
高对比度模式 备用高对比度资源
需要适用于不同 DPI 模式的多种资源 具有基于矢量回退功能的可选资源
重复图像 每个图像概念一个标识符

为什么采用图像服务?

  • 始终从 Visual Studio 获取最新的“完美像素”图像

  • 可以提交和使用自己的图像

  • 当 Windows 添加新的 DPI 缩放时,无需测试图像

  • 解决实施中的旧架构障碍

    使用图像服务前后的 Visual Studio shell 工具栏:

    使用图像服务之前和之后

工作原理

图像服务可以提供适合任何支持的 UI 框架的位图图像:

  • WPF:BitmapSource

  • WinForms:System.Drawing.Bitmap

  • Win32:HBITMAP

    图像服务流程图

    图像服务流程图

    图像名字对象

    图像名字对象(或简称名字对象)是一个 GUID/ID 对,用于唯一标识图像库中的图像资产或图像列表资产。

    已知名字对象

    Visual Studio 图像目录中包含的图像名字对象集,可由任何 Visual Studio 组件或扩展公开使用。

    图像清单文件

    图像清单 (.imagemanifest) 文件是定义一组图像资产的 XML 文件、表示这些资产的名字对象,以及表示每个资产的真实图像或图像。 图像清单可以为旧版 UI 支持定义独立图像或图像列表。 此外,还可以在每个资产后面的单个图像上设置属性,以更改这些资产的显示时间和方式。

    图像清单架构

    完整的图像清单如下所示:

<ImageManifest>
      <!-- zero or one Symbols elements -->
      <Symbols>
        <!-- zero or more Import, Guid, ID, or String elements -->
      </Symbols>
      <!-- zero or one Images elements -->
      <Images>
        <!-- zero or more Image elements -->
      </Images>
      <!-- zero or one ImageLists elements -->
      <ImageLists>
        <!-- zero or more ImageList elements -->
      </ImageLists>
</ImageManifest>

符号

。作为可读性和维护帮助,图像清单可以使用符号作为属性值。 符号定义如下:

<Symbols>
      <Import Manifest="manifest" />
      <Guid Name="ShellCommandGuid" Value="8ee4f65d-bab4-4cde-b8e7-ac412abbda8a" />
      <ID Name="cmdidSaveAll" Value="1000" />
      <String Name="AssemblyName" Value="Microsoft.VisualStudio.Shell.UI.Internal" />
      <!-- If your assembly is strongly named, you'll need the version and public key token as well -->
      <!-- <String Name="AssemblyName" Value="Microsoft.VisualStudio.Shell.UI.Internal;v17.0.0.0;b03f5f7f11d50a3a" /> -->
</Symbols>
子元素 定义
Import 导入给定清单文件的符号,以便在当前清单中使用
Guid 该符号表示 GUID,必须与 GUID 格式匹配
ID 该符号表示 ID,必须为非负整数
String 该符号表示任意字符串值

符号区分大小写,并使用 $(symbol-name) 语法引用:

<Image Guid="$(ShellCommandGuid)" ID="$(cmdidSaveAll)" >
      <Source Uri="/$(AssemblyName);Component/Resources/image.xaml" />
</Image>

有些符号是为所有清单预定义的。 这些符号可以在 <Source> 或 <Import> 元素的 Uri 属性中使用,以引用本地计算机上的路径。

符号 描述
CommonProgramFiles %CommonProgramFiles% 环境变量的值
LocalAppData %LocalAppData% 环境变量的值
ManifestFolder 包含清单文件的文件夹
MyDocuments 当前用户的“我的文档”文件夹的完整路径
ProgramFiles %ProgramFiles% 环境变量的值
System Windows\System32 文件夹
WinDir %WinDir% 环境变量的值

Image

<Image> 元素定义可由名字对象引用的图像。 GUID 和 ID 共同构成图像名字对象。 图像的名字对象在整个图像库中必须是唯一的。 如果多个图像具有给定的名字对象,则将保留构建库时遇到的第一个图像。

必须包含至少一个源。 中性尺寸的源可在各种尺寸中提供最佳效果,但这不是必需的。 如果服务请求的图像尺寸未在 <Image> 元素中定义,并且没有中性尺寸的源,则服务将选择最佳的特定尺寸的源并将其缩放到请求的尺寸。

<Image Guid="guid" ID="int" AllowColorInversion="true/false">
      <Source ... />
      <!-- optional additional Source elements -->
</Image>
属性 定义
Guid [必需]图像名字对象的 GUID 部分
ID [必需]图像名字对象的 ID 部分
AllowColorInversion [可选,默认值为 true]指示在深色背景上使用图像时,是否可以以编程方式反转其颜色。

Source

<Source> 元素定义单个图像源资产(XAML 和 PNG)。

<Source Uri="uri" Background="background">
      <!-- optional NativeResource element -->
 </Source>
属性 定义
Uri [必需]一个 URI,用于定义可从中加载图像的位置。 该参数可以是下列值之一:

- 使用 application:/// 权限的 Pack URI
- 绝对的组件资源参考
- 包含本机资源的文件的路径
背景 [可选]指示源要使用的背景类型。

该参数可以是下列值之一:

浅色:源可用于浅色背景。

深色:源可用于深色背景。

HighContrast:源可在高对比度模式下的任何背景上使用。

HighContrastLight:源可在高对比度模式下的浅色背景上使用。

HighContrastDark:源可在高对比度模式下的深色背景上使用。

如果省略背景属性,则可以在任何背景上使用源。

如果背景为 LightDarkHighContrastLightHighContrastDark,则源的颜色永远不会反转。 如果省略“背景”或将其设置为 HighContrast,则源颜色的反转由图像的 AllowColorInversion 属性控制。

<Source> 元素可以正好具有以下可选子元素之一:

元素 属性(全部必需) 定义
<大小> 源将用于给定尺寸的图像(以设备单元表示)。 图像将为正方形。
<SizeRange> MinSize、MaxSize 源将用于从 MinSize 到 MaxSize(含两者)的图像(以设备单元表示)。 图像将为正方形。
<Dimensions> Width, Height 源将用于给定宽度和高度的图像(以设备单元表示)。
<DimensionRange> MinWidth、MinHeight、

MaxWidth、MaxHeight
源将用于从最小宽度/高度到最大宽度/高度的图像(以设备单元表示)。

<Source> 元素还可以具有可选的 <NativeResource> 子元素,该子元素定义从本机程序集而不是托管程序集加载的 <Source>。

<NativeResource Type="type" ID="int" />
属性 定义
类型 [必需]本机资源的类型,即 XAML 或 PNG
ID [必需]本机资源的整数 ID 部分

ImageList

<ImageList> 元素定义可在单个条带中返回的图像集合。 条带按需构建。

<ImageList>
      <ContainedImage Guid="guid" ID="int" External="true/false" />
      <!-- optional additional ContainedImage elements -->
 </ImageList>
属性 定义
Guid [必需]图像名字对象的 GUID 部分
ID [必需]图像名字对象的 ID 部分
外部 [可选,默认值为 false]指示图像名字对象是否引用当前清单中的图像。

包含图像的名字对象不必引用当前清单中定义的图像。 如果在图像库中找不到包含的图像,则将使用空白占位符图像来代替它。

使用图像服务

初始步骤(托管)

若要使用图像服务,需要向项目添加对部分或全部程序集的引用:

  • Microsoft.VisualStudio.ImageCatalog.dll

    • 如果使用内置图像目录 KnownMonikers,则为必需项。
  • Microsoft.VisualStudio.Imaging.dll

    • 如果在 WPF UI 中使用 CrispImageImageThemingUtilities,则为必需项。
  • Microsoft.VisualStudio.Imaging.Interop.14.0.DesignTime.dll

    • 如果使用 ImageMonikerImageAttributes 类型,则为必需项。

    • EmbedInteropTypes 应设置为 true。

  • Microsoft.VisualStudio.Shell.Interop.14.0.DesignTime

    • 如果使用 IVsImageService2 类型,则为必需项。

    • EmbedInteropTypes 应设置为 true。

  • Microsoft.VisualStudio.Utilities.dll

    • 如果对 WPF UI 中的 ImageThemingUtilities.ImageBackgroundColor 使用 BrushToColorConverter,则为必需项。
  • Microsoft.VisualStudio.Shell.<VSVersion>.0

    • 如果使用 IVsUIObject 类型,则为必需项。
  • Microsoft.VisualStudio.Shell.Interop.10.0.dll

    • 如果使用与 WinForms 相关的 UI 帮助程序,则为必需项。

    • EmbedInteropTypes 应设置为 true

初始步骤(本机)

若要使用图像服务,则需要将以下部分或全部标头包含到项目中:

  • KnownImageIds.h

    • 如果使用内置图像目录 KnownMonikers,但无法使用 ImageMoniker 类型(例如从 IVsHierarchy GetGuidPropertyGetProperty 调用返回值时),则为必需项。
  • KnownMonikers.h

    • 如果使用内置图像目录 KnownMonikers,则为必需项。
  • ImageParameters140.h

    • 如果使用 ImageMonikerImageAttributes 类型,则为必需项。
  • VSShell140.h

    • 如果使用 IVsImageService2 类型,则为必需项。
  • ImageThemingUtilities.h

    • 如果无法让图像服务为你处理主题,则为必需项。

    • 如果图像服务可以处理图像主题,请不要使用此标头。

  • VsDpiAwareness.h

    • 如果使用 DPI 感知帮助程序获取当前 DPI,则为必需项。

如何编写新的 WPF UI?

  1. 首先将上面“初始步骤”部分所需的程序集引用添加到项目。 无需添加所有这些引用,因此只需添加所需的引用。 (注意:如果你正在使用或有权访问颜色而不是画笔,则可以跳过对实用程序的引用,因为你不需要转换器。)

  2. 选择所需的图像并获取其名字对象。 使用 KnownMoniker,如果你拥有自己的自定义映像和名字对象,请使用自己的映像和名字对象。

  3. CrispImages 添加到 XAML。 (请参阅下面的示例。)

  4. 在 UI 层次结构中设置 ImageThemingUtilities.ImageBackgroundColor 属性。 (这应该在已知背景色的位置设置,不一定在 CrispImage 上。)(请参阅下面的示例。)

<Window
  x:Class="WpfApplication.MainWindow"
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  xmlns:imaging="clr-namespace:Microsoft.VisualStudio.Imaging;assembly=Microsoft.VisualStudio.Imaging"
  xmlns:theming="clr-namespace:Microsoft.VisualStudio.PlatformUI;assembly=Microsoft.VisualStudio.Imaging"
  xmlns:utilities="clr-namespace:Microsoft.VisualStudio.PlatformUI;assembly=Microsoft.VisualStudio.Utilities"
  xmlns:catalog="clr-namespace:Microsoft.VisualStudio.Imaging;assembly=Microsoft.VisualStudio.ImageCatalog"
  Title="MainWindow" Height="350" Width="525" UseLayoutRounding="True">
  <Window.Resources>
    <utilities:BrushToColorConverter x:Key="BrushToColorConverter"/>
  </Window.Resources>
  <StackPanel Background="White" VerticalAlignment="Center"
    theming:ImageThemingUtilities.ImageBackgroundColor="{Binding Background, RelativeSource={RelativeSource Self}, Converter={StaticResource BrushToColorConverter}}">
    <imaging:CrispImage Width="16" Height="16" Moniker="{x:Static catalog:KnownMonikers.MoveUp}" />
  </StackPanel>
</Window>

如何更新现有的 WPF UI?

更新现有 WPF UI 是一个相对简单的过程,包含三个基本步骤:

  1. 将 UI 中的所有 <Image> 元素替换为 <CrispImage> 元素。

  2. 将所有 Source 属性更改为 Moniker 属性。

    • 如果图像永远不会更改,并且你正在使用 KnownMonikers,则将该属性静态绑定到 KnownMoniker。 (请参阅上面的示例。)

    • 如果图像永远不会更改,并且你使用的是自己的自定义图像,则静态绑定到自己的名字对象。

    • 如果图像可以更改,请将 Moniker 属性绑定到通知属性更改的代码属性。

  3. 在 UI 层次结构中的某个位置,设置 ImageThemingUtilities.ImageBackgroundColor 以确保颜色反转正常工作。

    • 这可能需要使用 BrushToColorConverter 类。 (请参阅上面的示例。)

如何更新 Win32 UI?

在适当位置将以下内容添加到代码中,以替换图像的原始加载。 根据需要切换用于返回 HBITMAP、HICON 与 HIMAGELIST 的值。

获取图像服务

CComPtr<IVsImageService2> spImgSvc;
CGlobalServiceProvider::HrQueryService(SID_SVsImageService, &spImgSvc);

请求图像

UINT dpiX, dpiY;
HWND hwnd = // get the HWND where the image will be displayed
VsUI::CDpiAwareness::GetDpiForWindow(hwnd, &dpiX, &dpiY);

ImageAttributes attr = { 0 };
attr.StructSize      = sizeof(attributes);
attr.Format          = DF_Win32;
// IT_Bitmap for HBITMAP, IT_Icon for HICON, IT_ImageList for HIMAGELIST
attr.ImageType       = IT_Bitmap;
attr.LogicalWidth    = 16;
attr.LogicalHeight   = 16;
attr.Dpi             = dpiX;
// Desired RGBA color, if you don't use this, don't set IAF_Background below
attr.Background      = 0xFFFFFFFF;
attr.Flags           = IAF_RequiredFlags | IAF_Background;

CComPtr<IVsUIObject> spImg;
// Replace this KnownMoniker with your desired ImageMoniker
spImgSvc->GetImage(KnownMonikers::Blank, attributes, &spImg);

如何更新 WinForms UI?

在适当位置将以下内容添加到代码中,以替换图像的原始加载。 根据需要切换用于返回位图与图标的值。

有用的 using 语句

using GelUtilities = Microsoft.Internal.VisualStudio.PlatformUI.Utilities;

获取图像服务

// This or your preferred way of querying for Visual Studio services
IVsImageService2 imageService = (IVsImageService2)Package.GetGlobalService(typeof(SVsImageService));

请求图像

Control control = // get the control where the image will be displayed

ImageAttributes attributes = new ImageAttributes
{
    StructSize    = Marshal.SizeOf(typeof(ImageAttributes)),
    // IT_Bitmap for Bitmap, IT_Icon for Icon, IT_ImageList for ImageList
    ImageType     = (uint)_UIImageType.IT_Bitmap,
    Format        = (uint)_UIDataFormat.DF_WinForms,
    LogicalWidth  = 16,
    LogicalHeight = 16,
    Dpi           = (int)DpiAwareness.GetWindowDpi(control.Handle);
    // Desired RGBA color, if you don't use this, don't set IAF_Background below
    Background    = 0xFFFFFFFF,
    Flags         = unchecked((uint)_ImageAttributesFlags.IAF_RequiredFlags | _ImageAttributesFlags.IAF_Background),
};

// Replace this KnownMoniker with your desired ImageMoniker
IVsUIObject uIObj = imageService.GetImage(KnownMonikers.Blank, attributes);

Bitmap bitmap = (Bitmap)GelUtilities.GetObjectData(uiObj); // Use this if you need a bitmap
// Icon icon = (Icon)GelUtilities.GetObjectData(uiObj);    // Use this if you need an icon

如何在新工具窗口中使用图像名字对象?

VSIX 包项目模板已针对 Visual Studio 2015 进行了更新。 若要创建新工具窗口,请右键单击 VSIX 项目,然后选择添加>新项 (Ctrl+Shift+A)。 在项目语言的扩展性节点下,选择“自定义工具窗口”,为工具窗口命名,然后按添加按钮。

以下是在工具窗口中使用名字对象的关键位置。 请按照每个位置的说明进行操作:

  1. 当选项卡足够小时,则在“工具窗口”选项卡中使用(也在 Ctrl+Tab 窗口切换器中使用)。

    将此行添加到派生自 ToolWindowPane 类型的类的构造函数:

    // Replace this KnownMoniker with your desired ImageMoniker
    this.BitmapImageMoniker = KnownMonikers.Blank;
    
  2. 用于打开工具窗口的命令。

    .vsct 包的文件中,编辑工具窗口的命令按钮:

    <Button guid="guidPackageCmdSet" id="CommandId" priority="0x0100" type="Button">
      <Parent guid="guidSHLMainMenu" id="IDG_VS_WNDO_OTRWNDWS1"/>
      <!-- Replace this KnownMoniker with your desired ImageMoniker -->
      <Icon guid="ImageCatalogGuid" id="Blank" />
      <!-- Add this -->
      <CommandFlag>IconIsMoniker</CommandFlag>
      <Strings>
        <ButtonText>MyToolWindow</ButtonText>
      </Strings>
    </Button>
    

    确保以下内容也存在于文件顶部的 <Extern> 元素之后:

    <Include href="KnownImageIds.vsct"/>
    

如何在现有工具窗口中使用图像名字对象?

更新现有工具窗口以使用图像名字对象的步骤与创建新工具窗口相似。

以下是在工具窗口中使用名字对象的关键位置。 请按照每个位置的说明进行操作:

  1. 当选项卡足够小时,则在“工具窗口”选项卡中使用(也在 Ctrl+Tab 窗口切换器中使用)。

    1. 从派生自 ToolWindowPane 类型的类的构造函数中删除这些行(如果存在):

      this.BitmapResourceID = <Value>;
      this.BitmapIndex = <Value>;
      
    2. 请参阅上面的“如何在新工具窗口中使用图像名字对象?”部分的步骤 1。

  2. 用于打开工具窗口的命令。

    • 请参阅上面的“如何在新工具窗口中使用图像名字对象?”部分的步骤 2。

如何在 .vsct 文件中使用图像名字对象?

按以下注释行的指示更新 .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">
  <!--  Include the definitions for images included in the VS image catalog -->
  <Include href="KnownImageIds.vsct"/>
  <Commands package="guidMyPackage">
    <Buttons>
      <Button guid="guidMyCommandSet" id="cmdidMyCommand" priority="0x0000" type="Button">
        <!-- Add an Icon element, changing the attributes to match the image moniker you want to use.
             In this case, we're using the Guid for the VS image catalog.
             Change the id attribute to be the ID of the desired image moniker. -->
        <Icon guid="ImageCatalogGuid" id="OpenFolder" />
        <CommandFlag>DynamicVisibility</CommandFlag>
        <CommandFlag>DefaultInvisible</CommandFlag>
        <CommandFlag>DefaultDisabled</CommandFlag>
        <CommandFlag>CommandWellOnly</CommandFlag>
        <CommandFlag>IconAndText</CommandFlag>
        <!-- Add the IconIsMoniker CommandFlag -->
        <CommandFlag>IconIsMoniker</CommandFlag>
        <Strings>
          <ButtonText>Quick Fixes...</ButtonText>
          <CommandName>Show Quick Fixes</CommandName>
          <CanonicalName>ShowQuickFixes</CanonicalName>
          <LocCanonicalName>ShowQuickFixes</LocCanonicalName>
        </Strings>
      </Button>
    </Buttons>
  </Commands>
  <!-- It is recommended that you remove <Bitmap> elements that are no longer used in the vsct file -->
  <Symbols>
    <GuidSymbol name="guidMyPackage"    value="{1491e936-6ffe-474e-8371-30e5920d8fdd}" />
    <GuidSymbol name="guidMyCommandSet" value="{10347de4-69a9-47f4-a950-d3301f6d2bc7}">
      <IDSymbol name="cmdidMyCommand" value="0x9437" />
    </GuidSymbol>
  </Symbols>
</CommandTable>

如果我的 .vsct 文件还需要由旧版本的 Visual Studio 读取,该怎么办?

旧版本的 Visual Studio 无法识别 IconIsMoniker 命令标志。 可以在支持图像服务的 Visual Studio 版本上使用图像服务中的图像,但在旧版本的 Visual Studio 上继续使用旧式图像。 为此,需要将 .vsct 文件保持不变(因此与旧版本的 Visual Studio 兼容),并创建一个 CSV(逗号分隔值)文件,该文件从 .vsct 文件的 <Bitmaps> 元素 中定义的 GUID/ID 对映射到图像名字对象 GUID/ID 对。

映射 CSV 文件的格式为:

Icon guid, Icon id, Moniker guid, Moniker id
b714fcf7-855e-4e4c-802a-1fd87144ccad,1,fda30684-682d-421c-8be4-650a2967058e,100
b714fcf7-855e-4e4c-802a-1fd87144ccad,2,fda30684-682d-421c-8be4-650a2967058e,200

CSV 文件随包一起部署,其位置由 ProvideMenuResource 包属性的 IconMappingFilename 属性指定:

[ProvideMenuResource("MyPackage.ctmenu", 1, IconMappingFilename="IconMappings.csv")]

IconMappingFilename 可以以 $PackageFolder$ 的相对路径(如上例所示)为隐式根目录,或者以环境变量定义的目录的绝对路径,如 @"%UserProfile%\dir1\dir2\MyMappingFile.csv" 为显式根目录。

如何移植项目系统?

如何为项目提供 ImageMonikers

  1. 在项目的 IVsHierarchy 上实施 VSHPROPID_SupportsIconMonikers,并返回 true。

  2. 实施 VSHPROPID_IconMonikerImageList(如果原始项目使用 VSHPROPID_IconImgList)或 VSHPROPID_IconMonikerGuidVSHPROPID_IconMonikerIdVSHPROPID_OpenFolderIconMonikerGuidVSHPROPID_OpenFolderIconMonikerId(如果原始项目使用 VSHPROPID_IconHandleVSHPROPID_OpenFolderIconHandle)。

  3. 更改图标的原始 VSHPROPID 的实施,以便在扩展点请求它们时创建图标的“旧”版本。 IVsImageService2 提供获取这些图标所需的功能

    VB/C# 项目风格的额外要求

    仅当检测到项目是最外层的风格时,才实施 VSHPROPID_SupportsIconMonikers。 否则,真实的最外层风格实际上可能不支持图像名称,并且基本风格可能会有效地“隐藏”自定义图像。

    如何在 CPS 中使用图像名称?

    可以手动或通过项目系统扩展性 SDK 附带的项目模板在 CPS(通用项目系统)中设置自定义图像。

    使用项目系统扩展性 SDK

    按照“为项目类型/项目类型提供自定义图标”中的说明自定义 CPS 图像。 有关 CPS 的详细信息,请参阅 Visual Studio 项目系统扩展性文档

    手动使用 ImageMonikers

  4. 在项目系统中实施和导出 IProjectTreeModifier 接口。

  5. 确定要使用的 KnownMoniker 或自定义图像名字对象。

  6. ApplyModifications 方法中,在返回新树之前,在方法中执行以下操作,如以下示例所示:

    // Replace this KnownMoniker with your desired ImageMoniker
    tree = tree.SetIcon(KnownMonikers.Blank.ToProjectSystemType());
    
  7. 如果要创建新树,可以通过将所需名字对象传入 NewTree 方法来设置自定义图像,如以下示例所示:

    // Replace this KnownMoniker with your desired ImageMoniker
    ProjectImageMoniker icon         = KnownMonikers.FolderClosed.ToProjectSystemType();
    ProjectImageMoniker expandedIcon = KnownMonikers.FolderOpened.ToProjectSystemType();
    
    return this.ProjectTreeFactory.Value.NewTree(/*caption*/<value>,
                                                 /*filePath*/<value>,
                                                 /*browseObjectProperties*/<value>,
                                                 icon,
                                                 expandedIcon);
    

如何从真实图像条带转换为基于名字对象的图像条带?

我需要支持 HIMAGELIST

如果代码已经有一个图像条带,你想要更新它以使用图像服务,但受到需要传递图像列表的 API 的限制,你仍然可以享受图像服务带来的好处。 若要创建基于名字对象的图像条带,请按照以下步骤从现有名字对象创建清单。

  1. 运行 ManifestFromResources 工具,向其传递图像条带。 这将为该条带生成清单。

    • 建议:为清单提供一个非默认名称,以适合其用法。
  2. 如果仅使用 KnownMonikers,请执行以下操作:

    • 将清单的 <Image> 部分替换为 <Images/>。

    • 删除所有子图像 ID(任何带有 <imagestrip name>_## 的 ID)。

    • 建议:重命名 AssetsGuid 符号和图像条带符号以适合其用法。

    • 将每个 ContainedImage 的 GUID 替换为 $(ImageCatalogGuid),将每个 ContainedImage 的 ID 替换为 $(<moniker>),然后向每个 ContainedImage 添加 External="true" 属性

      • <moniker> 应替换为与图像匹配的 KnownMoniker,但从名称中删除“KnownMonikers.”。
    • 将 <Import Manifest="$(ManifestFolder)\<Relative install dir path to *>\Microsoft.VisualStudio.ImageCatalog.imagemanifest" /*> 添加到 <Symbols> 部分顶部。

      • 相对路径由为清单创作设置时定义的部署位置确定。
  3. 运行 ManifestToCode 工具以生成包装器,这样,现有代码将具有一个名字对象,可用于查询图像服务的图像条带。

    • 建议:为包装器和命名空间提供非默认名称以适合其用法。
  4. 执行所有添加、设置创作/部署和其他代码更改以使用影像服务和新文件。包含内部和外部图像的清单示例,以查看其外观:

    示例清单,包括内部和外部图像,以查看其外观:

<?xml version="1.0"?>
<ImageManifest
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
  xmlns="http://schemas.microsoft.com/VisualStudio/ImageManifestSchema/2014">

  <Symbols>
    <!-- This needs to be the relative path from your manifest to the ImageCatalog's manifest
         where $(ManifestFolder) is the deployed location of this manifest. -->
    <Import Manifest="$(ManifestFolder)\<RelPath>\Microsoft.VisualStudio.ImageCatalog.imagemanifest" />

    <String Name="Resources" Value="/My.Assembly.Name;Component/Resources/ImageStrip" />
    <Guid Name="ImageGuid" Value="{fb41b7ef-6587-480c-aa27-5b559d42cfc9}" />
    <Guid Name="ImageStripGuid" Value="{9c84a570-d9a7-4052-a340-188fb276f973}" />
    <ID Name="MyImage_0" Value="100" />
    <ID Name="MyImage_1" Value="101" />
    <ID Name="InternalList" Value="1001" />
    <ID Name="ExternalList" Value="1002" />
  </Symbols>

  <Images>
    <Image Guid="$(ImageGuid)" ID="$(MyImage_0)">
      <Source Uri="$(Resources)/MyImage_0.png">
        <Size Value="16" />
      </Source>
    </Image>
    <Image Guid="$(ImageGuid)" ID="$(MyImage_1)">
      <Source Uri="$(Resources)/MyImage_1.png">
        <Size Value="16" />
      </Source>
    </Image>
  </Images>

  <ImageLists>
    <ImageList Guid="$(ImageStripGuid)" ID="$(InternalList)">
      <ContainedImage Guid="$(ImageGuid)" ID="$(MyImage_0)" />
      <ContainedImage Guid="$(ImageGuid)" ID="$(MyImage_1)" />
    </ImageList>
    <ImageList Guid="$(ImageStripGuid)" ID="$(ExternalList)">
      <ContainedImage Guid="$(ImageCatalogGuid)" ID="$(StatusError)" External="true" />
      <ContainedImage Guid="$(ImageCatalogGuid)" ID="$(StatusWarning)" External="true" />
      <ContainedImage Guid="$(ImageCatalogGuid)" ID="$(StatusInformation)" External="true" />
    </ImageList>
  </ImageLists>

</ImageManifest>

我不需要支持 HIMAGELIST

  1. 确定与图像条带中的图像匹配的 KnownMonikers 集,或为图像条带中的图像创建自己的名字对象。

  2. 更新用于获取图像条中所需索引处的图像的任何映射,以改用名字对象。

  3. 更新代码以使用图像服务通过更新的图像请求名字对象。 (这可能意味着更新到 CrispImages 以获取托管代码,或者从图像服务请求 HBITMAP 或 HICON,并将它们传递给本机代码。)

测试图像

可以使用图像库查看器工具测试图像清单,以确保正确创作所有内容。 可以在 Visual Studio 2015 SDK 中找到该工具。 此工具及其他工具的文档可在此处找到。

其他资源

示例

GitHub 上的几个 Visual Studio 示例已更新,以展示如何使用图像服务作为各种 Visual Studio 扩展点的一部分。

检查 http://github.com/Microsoft/VSSDK-Extensibility-Samples 获取最新示例。

工具

创建了一组图像服务支持工具,以帮助创建/更新与图像服务配合使用的 UI。 有关每个工具的更多信息,请查看工具附带的文档。 这些工具包含在 Visual Studio 2015 SDK 中。

ManifestFromResources

Manifest from Resources 工具获取图像资源(PNG 或 XAML)列表并生成图像清单文件,以便通过图像服务使用这些图像。

ManifestToCode

Manifest to Code 工具采用图像清单文件并生成包装器文件,用于引用代码(C++、C# 或 VB)或 .vsct 文件中的清单值。

ImageLibraryViewer

图片库查看器图像库查看器工具可以加载图像清单,并允许用户以与 Visual Studio 相同的方式操作它们,以确保正确编写清单。 用户可以更改背景、尺寸、DPI 设置、高对比度和其他设置。 它还显示加载信息以查找清单中的错误,并显示清单中每个图像的源信息。

常见问题解答

  • 加载 <Reference Include="Microsoft.VisualStudio.*.Interop.14.0.DesignTime" /> 时,时是否必须包含任何依赖项?

    • 在所有互操作 DLL 上设置 EmbedInteropTypes="true"。
  • 如何使用扩展部署映像清单?

    • .imagemanifest 文件添加到项目。

    • 将“包含在 VSIX 中”设置为“True”。

  • 我的映像仍然无法正常工作,我该如何找出问题所在?

    • Visual Studio 可能找不到映像清单。 出于性能原因,Visual Studio 限制了文件夹搜索深度,因此建议将映像清单保存在扩展的根文件夹中。

    • 映像清单文件中可能缺少程序集信息。 强命名的程序集需要其他信息才能由 Visual Studio 加载。 为了加载强名称程序集,你需要在映像清单中映像的资源 URI 中包含程序集版本和公钥令牌(以及程序集名称)。

      <ImageManifest xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://schemas.microsoft.com/VisualStudio/ImageManifestSchema/2014">
        <Symbols>
          <String Name="Resources" Value="/Microsoft.VisualStudio.Shell.UI.Internal;v17.0.0.0;b03f5f7f11d50a3a;Component/Resources" />
          ...
        </Symbols>
        ...
      </ImageManifest>
      
    • 你可能缺少映像程序集的代码库条目。 如果程序集在 Visual Studio 需要时尚未加载,则需要知道在何处查找程序集才能加载它。 要为程序集添加代码库,你可以使用 ProvideCodeBaseAttribute 来确保生成代码库条目并将其包含在扩展的 pkgdef 中。

      [assembly: ProvideCodeBase(AssemblyName = "ClassLibrary1", Version = "1.0.0.0", CodeBase = "$PackageFolder$\\ClassLibrary1.dll")]
      
    • 如果前面的选项不能解决映像加载问题,你可以通过将以下条目放入扩展中的 pkgdef 来启用日志记录:

      [$RootKey$\ImageLibrary]
      "TraceLevel"="Verbose"
      "TraceFilename"="ImageLibrary.log"
      

      这将在 %UserProfile% 文件夹中创建名为 ImageLibrary.log 的日志文件。 将这些条目添加到 pkgdef 后,请务必通过开发人员命令提示符运行“devenv /updateConfiguration”。 这可确保启用日志记录条目,并且 VS 会刷新映像清单缓存,以帮助查找读取映像清单时可能发生的任何错误。 如果随后演练需要加载映像的方案,则日志文件将包含映像的注册日志记录和请求日志记录。

  • 我正在更新 CPS 项目系统。 ImageName and StockIconService 发生了什么情况?

    • 当 CPS 更新为使用名字对象时,这些属性会被删除。 不再需要调用 StockIconService,只需使用 CPS 实用工具中的 ToProjectSystemType() 扩展方法将所需的 KnownMoniker 传递给方法或属性。 可以在下面找到从 ImageNameKnownMonikers 的映射:

      ImageName KnownMoniker
      ImageName.OfflineWebApp KnownImageIds.Web
      ImageName.WebReferencesFolder KnownImageIds.Web
      ImageName.OpenReferenceFolder KnownImageIds.FolderOpened
      ImageName.ReferenceFolder KnownImageIds.Reference
      ImageName.Reference KnownImageIds.Reference
      ImageName.SdlWebReference KnownImageIds.WebReferenceFolder
      ImageName.DiscoWebReference KnownImageIds.DynamicDiscoveryDocument
      ImageName.Folder KnownImageIds.FolderClosed
      ImageName.OpenFolder KnownImageIds.FolderOpened
      ImageName.ExcludedFolder KnownImageIds.HiddenFolderClosed
      ImageName.OpenExcludedFolder KnownImageIds.HiddenFolderOpened
      ImageName.ExcludedFile KnownImageIds.HiddenFile
      ImageName.DependentFile KnownImageIds.GenerateFile
      ImageName.MissingFile KnownImageIds.DocumentWarning
      ImageName.WindowsForm KnownImageIds.WindowsForm
      ImageName.WindowsUserControl KnownImageIds.UserControl
      ImageName.WindowsComponent KnownImageIds.ComponentFile
      ImageName.XmlSchema KnownImageIds.XMLSchema
      ImageName.XmlFile KnownImageIds.XMLFile
      ImageName.WebForm KnownImageIds.Web
      ImageName.WebService KnownImageIds.WebService
      ImageName.WebUserControl KnownImageIds.WebUserControl
      ImageName.WebCustomUserControl KnownImageIds.WebCustomControl
      ImageName.AspPage KnownImageIds.ASPFile
      ImageName.GlobalApplicationClass KnownImageIds.SettingsFile
      ImageName.WebConfig KnownImageIds.ConfigurationFile
      ImageName.HtmlPage KnownImageIds.HTMLFile
      ImageName.StyleSheet KnownImageIds.StyleSheet
      ImageName.ScriptFile KnownImageIds.JSScript
      ImageName.TextFile KnownImageIds.Document
      ImageName.SettingsFile KnownImageIds.Settings
      ImageName.Resources KnownImageIds.DocumentGroup
      ImageName.Bitmap KnownImageIds.Image
      ImageName.Icon KnownImageIds.IconFile
      ImageName.Image KnownImageIds.Image
      ImageName.ImageMap KnownImageIds.ImageMapFile
      ImageName.XWorld KnownImageIds.XWorldFile
      ImageName.Audio KnownImageIds.Sound
      ImageName.Video KnownImageIds.Media
      ImageName.Cab KnownImageIds.CABProject
      ImageName.Jar KnownImageIds.JARFile
      ImageName.DataEnvironment KnownImageIds.DataTable
      ImageName.PreviewFile KnownImageIds.Report
      ImageName.DanglingReference KnownImageIds.ReferenceWarning
      ImageName.XsltFile KnownImageIds.XSLTransform
      ImageName.Cursor KnownImageIds.CursorFile
      ImageName.AppDesignerFolder KnownImageIds.Property
      ImageName.Data KnownImageIds.Database
      ImageName.Application KnownImageIds.Application
      ImageName.DataSet KnownImageIds.DatabaseGroup
      ImageName.Pfx KnownImageIds.Certificate
      ImageName.Snk KnownImageIds.Rule
      ImageName.VisualBasicProject KnownImageIds.VBProjectNode
      ImageName.CSharpProject KnownImageIds.CSProjectNode
      ImageName.Empty KnownImageIds.Blank
      ImageName.MissingFolder KnownImageIds.FolderOffline
      ImageName.SharedImportReference KnownImageIds.SharedProject
      ImageName.SharedProjectCs KnownImageIds.CSSharedProject
      ImageName.SharedProjectVc KnownImageIds.CPPSharedProject
      ImageName.SharedProjectJs KnownImageIds.JSSharedProject
      ImageName.CSharpCodeFile KnownImageIds.CSFileNode
      ImageName.VisualBasicCodeFile KnownImageIds.VBFileNode
  • 我正在更新完成列表提供程序。 哪些 KnownMonikers 与旧的 StandardGlyphGroupStandardGlyph 值匹配?

    名称 名称 名称
    GlyphGroupClass GlyphItemPublic ClassPublic
    GlyphGroupClass GlyphItemInternal ClassInternal
    GlyphGroupClass GlyphItemFriend ClassInternal
    GlyphGroupClass GlyphItemProtected ClassProtected
    GlyphGroupClass GlyphItemPrivate ClassPrivate
    GlyphGroupClass GlyphItemShortcut ClassShortcut
    GlyphGroupConstant GlyphItemPublic ConstantPublic
    GlyphGroupConstant GlyphItemInternal ConstantInternal
    GlyphGroupConstant GlyphItemFriend ConstantInternal
    GlyphGroupConstant GlyphItemProtected ConstantProtected
    GlyphGroupConstant GlyphItemPrivate ConstantPrivate
    GlyphGroupConstant GlyphItemShortcut ConstantShortcut
    GlyphGroupDelegate GlyphItemPublic DelegatePublic
    GlyphGroupDelegate GlyphItemInternal DelegateInternal
    GlyphGroupDelegate GlyphItemFriend DelegateInternal
    GlyphGroupDelegate GlyphItemProtected DelegateProtected
    GlyphGroupDelegate GlyphItemPrivate DelegatePrivate
    GlyphGroupDelegate GlyphItemShortcut DelegateShortcut
    GlyphGroupEnum GlyphItemPublic EnumerationPublic
    GlyphGroupEnum GlyphItemInternal EnumerationInternal
    GlyphGroupEnum GlyphItemFriend EnumerationInternal
    GlyphGroupEnum GlyphItemProtected EnumerationProtected
    GlyphGroupEnum GlyphItemPrivate EnumerationPrivate
    GlyphGroupEnum GlyphItemShortcut EnumerationShortcut
    GlyphGroupEnumMember GlyphItemPublic EnumerationItemPublic
    GlyphGroupEnumMember GlyphItemInternal EnumerationItemInternal
    GlyphGroupEnumMember GlyphItemFriend EnumerationItemInternal
    GlyphGroupEnumMember GlyphItemProtected EnumerationItemProtected
    GlyphGroupEnumMember GlyphItemPrivate EnumerationItemPrivate
    GlyphGroupEnumMember GlyphItemShortcut EnumerationItemShortcut
    GlyphGroupEvent GlyphItemPublic EventPublic
    GlyphGroupEvent GlyphItemInternal EventInternal
    GlyphGroupEvent GlyphItemFriend EventInternal
    GlyphGroupEvent GlyphItemProtected EventProtected
    GlyphGroupEvent GlyphItemPrivate EventPrivate
    GlyphGroupEvent GlyphItemShortcut EventShortcut
    GlyphGroupException GlyphItemPublic ExceptionPublic
    GlyphGroupException GlyphItemInternal ExceptionInternal
    GlyphGroupException GlyphItemFriend ExceptionInternal
    GlyphGroupException GlyphItemProtected ExceptionProtected
    GlyphGroupException GlyphItemPrivate ExceptionPrivate
    GlyphGroupException GlyphItemShortcut ExceptionShortcut
    GlyphGroupField GlyphItemPublic FieldPublic
    GlyphGroupField GlyphItemInternal FieldInternal
    GlyphGroupField GlyphItemFriend FieldInternal
    GlyphGroupField GlyphItemProtected FieldProtected
    GlyphGroupField GlyphItemPrivate FieldPrivate
    GlyphGroupField GlyphItemShortcut FieldShortcut
    GlyphGroupInterface GlyphItemPublic InterfacePublic
    GlyphGroupInterface GlyphItemInternal InterfaceInternal
    GlyphGroupInterface GlyphItemFriend InterfaceInternal
    GlyphGroupInterface GlyphItemProtected InterfaceProtected
    GlyphGroupInterface GlyphItemPrivate InterfacePrivate
    GlyphGroupInterface GlyphItemShortcut InterfaceShortcut
    GlyphGroupMacro GlyphItemPublic MacroPublic
    GlyphGroupMacro GlyphItemInternal MacroInternal
    GlyphGroupMacro GlyphItemFriend MacroInternal
    GlyphGroupMacro GlyphItemProtected MacroProtected
    GlyphGroupMacro GlyphItemPrivate MacroPrivate
    GlyphGroupMacro GlyphItemShortcut MacroShortcut
    GlyphGroupMap GlyphItemPublic MapPublic
    GlyphGroupMap GlyphItemInternal MapInternal
    GlyphGroupMap GlyphItemFriend MapInternal
    GlyphGroupMap GlyphItemProtected MapProtected
    GlyphGroupMap GlyphItemPrivate MapPrivate
    GlyphGroupMap GlyphItemShortcut MapShortcut
    GlyphGroupMapItem GlyphItemPublic MapItemPublic
    GlyphGroupMapItem GlyphItemInternal MapItemInternal
    GlyphGroupMapItem GlyphItemFriend MapItemInternal
    GlyphGroupMapItem GlyphItemProtected MapItemProtected
    GlyphGroupMapItem GlyphItemPrivate MapItemPrivate
    GlyphGroupMapItem GlyphItemShortcut MapItemShortcut
    GlyphGroupMethod GlyphItemPublic MethodPublic
    GlyphGroupMethod GlyphItemInternal MethodInternal
    GlyphGroupMethod GlyphItemFriend MethodInternal
    GlyphGroupMethod GlyphItemProtected MethodProtected
    GlyphGroupMethod GlyphItemPrivate MethodPrivate
    GlyphGroupMethod GlyphItemShortcut MethodShortcut
    GlyphGroupOverload GlyphItemPublic MethodPublic
    GlyphGroupOverload GlyphItemInternal MethodInternal
    GlyphGroupOverload GlyphItemFriend MethodInternal
    GlyphGroupOverload GlyphItemProtected MethodProtected
    GlyphGroupOverload GlyphItemPrivate MethodPrivate
    GlyphGroupOverload GlyphItemShortcut MethodShortcut
    GlyphGroupModule GlyphItemPublic ModulePublic
    GlyphGroupModule GlyphItemInternal ModuleInternal
    GlyphGroupModule GlyphItemFriend ModuleInternal
    GlyphGroupModule GlyphItemProtected ModuleProtected
    GlyphGroupModule GlyphItemPrivate ModulePrivate
    GlyphGroupModule GlyphItemShortcut ModuleShortcut
    GlyphGroupNamespace GlyphItemPublic NamespacePublic
    GlyphGroupNamespace GlyphItemInternal NamespaceInternal
    GlyphGroupNamespace GlyphItemFriend NamespaceInternal
    GlyphGroupNamespace GlyphItemProtected NamespaceProtected
    GlyphGroupNamespace GlyphItemPrivate NamespacePrivate
    GlyphGroupNamespace GlyphItemShortcut NamespaceShortcut
    GlyphGroupOperator GlyphItemPublic OperatorPublic
    GlyphGroupOperator GlyphItemInternal OperatorInternal
    GlyphGroupOperator GlyphItemFriend OperatorInternal
    GlyphGroupOperator GlyphItemProtected OperatorProtected
    GlyphGroupOperator GlyphItemPrivate OperatorPrivate
    GlyphGroupOperator GlyphItemShortcut OperatorShortcut
    GlyphGroupProperty GlyphItemPublic PropertyPublic
    GlyphGroupProperty GlyphItemInternal PropertyInternal
    GlyphGroupProperty GlyphItemFriend PropertyInternal
    GlyphGroupProperty GlyphItemProtected PropertyProtected
    GlyphGroupProperty GlyphItemPrivate PropertyPrivate
    GlyphGroupProperty GlyphItemShortcut PropertyShortcut
    GlyphGroupStruct GlyphItemPublic StructurePublic
    GlyphGroupStruct GlyphItemInternal StructureInternal
    GlyphGroupStruct GlyphItemFriend StructureInternal
    GlyphGroupStruct GlyphItemProtected StructureProtected
    GlyphGroupStruct GlyphItemPrivate StructurePrivate
    GlyphGroupStruct GlyphItemShortcut StructureShortcut
    GlyphGroupTemplate GlyphItemPublic TemplatePublic
    GlyphGroupTemplate GlyphItemInternal TemplateInternal
    GlyphGroupTemplate GlyphItemFriend TemplateInternal
    GlyphGroupTemplate GlyphItemProtected TemplateProtected
    GlyphGroupTemplate GlyphItemPrivate TemplatePrivate
    GlyphGroupTemplate GlyphItemShortcut TemplateShortcut
    GlyphGroupTypedef GlyphItemPublic TypeDefinitionPublic
    GlyphGroupTypedef GlyphItemInternal TypeDefinitionInternal
    GlyphGroupTypedef GlyphItemFriend TypeDefinitionInternal
    GlyphGroupTypedef GlyphItemProtected TypeDefinitionProtected
    GlyphGroupTypedef GlyphItemPrivate TypeDefinitionPrivate
    GlyphGroupTypedef GlyphItemShortcut TypeDefinitionShortcut
    GlyphGroupType GlyphItemPublic TypePublic
    GlyphGroupType GlyphItemInternal TypeInternal
    GlyphGroupType GlyphItemFriend TypeInternal
    GlyphGroupType GlyphItemProtected TypeProtected
    GlyphGroupType GlyphItemPrivate TypePrivate
    GlyphGroupType GlyphItemShortcut TypeShortcut
    GlyphGroupUnion GlyphItemPublic UnionPublic
    GlyphGroupUnion GlyphItemInternal UnionInternal
    GlyphGroupUnion GlyphItemFriend UnionInternal
    GlyphGroupUnion GlyphItemProtected UnionProtected
    GlyphGroupUnion GlyphItemPrivate UnionPrivate
    GlyphGroupUnion GlyphItemShortcut UnionShortcut
    GlyphGroupVariable GlyphItemPublic FieldPublic
    GlyphGroupVariable GlyphItemInternal FieldInternal
    GlyphGroupVariable GlyphItemFriend FieldInternal
    GlyphGroupVariable GlyphItemProtected FieldProtected
    GlyphGroupVariable GlyphItemPrivate FieldPrivate
    GlyphGroupVariable GlyphItemShortcut FieldShortcut
    GlyphGroupValueType GlyphItemPublic ValueTypePublic
    GlyphGroupValueType GlyphItemInternal ValueTypeInternal
    GlyphGroupValueType GlyphItemFriend ValueTypeInternal
    GlyphGroupValueType GlyphItemProtected ValueTypeProtected
    GlyphGroupValueType GlyphItemPrivate ValueTypePrivate
    GlyphGroupValueType GlyphItemShortcut ValueTypeShortcut
    GlyphGroupIntrinsic GlyphItemPublic ObjectPublic
    GlyphGroupIntrinsic GlyphItemInternal ObjectInternal
    GlyphGroupIntrinsic GlyphItemFriend ObjectInternal
    GlyphGroupIntrinsic GlyphItemProtected ObjectProtected
    GlyphGroupIntrinsic GlyphItemPrivate ObjectPrivate
    GlyphGroupIntrinsic GlyphItemShortcut ObjectShortcut
    GlyphGroupJSharpMethod GlyphItemPublic MethodPublic
    GlyphGroupJSharpMethod GlyphItemInternal MethodInternal
    GlyphGroupJSharpMethod GlyphItemFriend MethodInternal
    GlyphGroupJSharpMethod GlyphItemProtected MethodProtected
    GlyphGroupJSharpMethod GlyphItemPrivate MethodPrivate
    GlyphGroupJSharpMethod GlyphItemShortcut MethodShortcut
    GlyphGroupJSharpField GlyphItemPublic FieldPublic
    GlyphGroupJSharpField GlyphItemInternal FieldInternal
    GlyphGroupJSharpField GlyphItemFriend FieldInternal
    GlyphGroupJSharpField GlyphItemProtected FieldProtected
    GlyphGroupJSharpField GlyphItemPrivate FieldPrivate
    GlyphGroupJSharpField GlyphItemShortcut FieldShortcut
    GlyphGroupJSharpClass GlyphItemPublic ClassPublic
    GlyphGroupJSharpClass GlyphItemInternal ClassInternal
    GlyphGroupJSharpClass GlyphItemFriend ClassInternal
    GlyphGroupJSharpClass GlyphItemProtected ClassProtected
    GlyphGroupJSharpClass GlyphItemPrivate ClassPrivate
    GlyphGroupJSharpClass GlyphItemShortcut ClassShortcut
    GlyphGroupJSharpNamespace GlyphItemPublic NamespacePublic
    GlyphGroupJSharpNamespace GlyphItemInternal NamespaceInternal
    GlyphGroupJSharpNamespace GlyphItemFriend NamespaceInternal
    GlyphGroupJSharpNamespace GlyphItemProtected NamespaceProtected
    GlyphGroupJSharpNamespace GlyphItemPrivate NamespacePrivate
    GlyphGroupJSharpNamespace GlyphItemShortcut NamespaceShortcut
    GlyphGroupJSharpInterface GlyphItemPublic InterfacePublic
    GlyphGroupJSharpInterface GlyphItemInternal InterfaceInternal
    GlyphGroupJSharpInterface GlyphItemFriend InterfaceInternal
    GlyphGroupJSharpInterface GlyphItemProtected InterfaceProtected
    GlyphGroupJSharpInterface GlyphItemPrivate InterfacePrivate
    GlyphGroupJSharpInterface GlyphItemShortcut InterfaceShortcut
    GlyphGroupError StatusError
    GlyphBscFile ClassFile
    GlyphAssembly 参考
    GlyphLibrary
    GlyphVBProject VBProjectNode
    GlyphCoolProject CSProjectNode
    GlyphCppProject CPPProjectNode
    GlyphDialogId 对话框
    GlyphOpenFolder FolderOpened
    GlyphClosedFolder FolderClosed
    GlyphArrow GoToNext
    GlyphCSharpFile CSFileNode
    GlyphCSharpExpansion 片段
    GlyphKeyword IntellisenseKeyword
    GlyphInformation StatusInformation
    GlyphReference ClassMethodReference
    GlyphRecursion 递归
    GlyphXmlItem 标记
    GlyphJSharpProject DocumentCollection
    GlyphJSharpDocument Document
    GlyphForwardType GoToNext
    GlyphCallersGraph CallTo
    GlyphCallGraph CallFrom
    GlyphWarning StatusWarning
    GlyphMaybeReference QuestionMark
    GlyphMaybeCaller CallTo
    GlyphMaybeCall CallFrom
    GlyphExtensionMethod ExtensionMethod
    GlyphExtensionMethodInternal ExtensionMethod
    GlyphExtensionMethodFriend ExtensionMethod
    GlyphExtensionMethodProtected ExtensionMethod
    GlyphExtensionMethodPrivate ExtensionMethod
    GlyphExtensionMethodShortcut ExtensionMethod
    GlyphXmlAttribute XmlAttribute
    GlyphXmlChild XmlElement
    GlyphXmlDescendant XmlDescendant
    GlyphXmlNamespace XmlNamespace
    GlyphXmlAttributeQuestion XmlAttributeLowConfidence
    GlyphXmlAttributeCheck XmlAttributeHighConfidence
    GlyphXmlChildQuestion XmlElementLowConfidence
    GlyphXmlChildCheck XmlElementHighConfidence
    GlyphXmlDescendantQuestion XmlDescendantLowConfidence
    GlyphXmlDescendantCheck XmlDescendantHighConfidence
    GlyphCompletionWarning IntellisenseWarning