对设计器或设计器组件关联的元数据和筛选属性的操作为应用程序提供了一种机制,从而定义特定设计器使用哪些工具来处理不同的Type对象(例如数据结构、类或图形实体),确定设计器何时可用,以及如何配置 Visual Studio IDE 以支持设计器(例如,哪些工具箱类别或选项卡可用)。
Visual Studio SDK 提供了多种机制,以便于控制设计器或其组件的初始化以及 VSPackage 对其元数据的操作。
初始化元数据和配置信息
由于 VSPackage 是按需加载的,因此在设计器实例化之前,Visual Studio 环境可能尚未加载 VSPackage。 因此,VSPackages 无法使用标准机制在创建时配置设计器或设计器组件,即处理 DesignerCreated 事件。 相反,VSPackage 实现 DesignSurfaceExtension 接口的一个实例并注册自身,以提供称为设计界面扩展的自定义功能。
自定义初始化
自定义设计器、组件或设计器界面涉及:
修改设计器元数据,并有效更改特定Type的访问或转换方式。
这种情况通常通过UITypeEditor或TypeConverter机制完成。
例如,当基于System.Windows.Forms设计器的设计器初始化时,Visual Studio 环境会修改与该设计器一起使用的Image对象,以使用资源管理器来获取位图而不是依赖文件系统。
例如,通过订阅事件或获取项目配置信息来与环境集成。 可以通过获取 ITypeResolutionService 接口来获取项目配置信息并订阅事件。
通过激活适当的 工具箱 类别或通过将类实例 ToolboxItemFilterAttribute 应用于设计器来限制设计器的适用性来修改用户环境。
由 VSPackage 执行的设计器初始化
VSPackage 应通过以下方式处理设计器初始化:
创建实现 DesignSurfaceExtension 类的对象。
注释
DesignSurfaceExtension类和Package类不应同时在同一对象上实现。
注册该实现 DesignSurfaceExtension 的类,以提供对 VSPackage 设计器扩展的支持。 通过将DesignSurfaceExtensionAttribute、ProvideObjectAttribute 和ProvideServiceAttribute的实例应用于提供 VSPackage Package 实现的类来注册该类。
每当创建设计器或设计器组件时,Visual Studio 环境会:
访问每个已注册的设计界面扩展提供程序。
实例化和初始化每个设计图面扩展提供程序的 DesignSurfaceExtension 对象的实例。
调用每个设计图面扩展提供程序的 OnDesignerCreated 方法或 OnComponentCreated 方法(视情况而定)。
在将DesignSurfaceExtension对象实现为VSPackage的成员时,务必要了解:
Visual Studio 环境不具备对特定
DesignSurfaceExtension提供程序所修改的元数据或其他配置设置的任何控制。 有可能存在两个或多个DesignSurfaceExtension提供程序以互相冲突的方式修改同一设计器功能,而最终的修改是确定性的。 无法确定最后应用的是哪个修改。可以通过将ToolboxItemFilterAttribute应用于该实现,显式地将DesignSurfaceExtension对象的实现限制为特定的设计器。 有关 工具箱 项筛选的详细信息,请参阅 ToolboxItemFilterAttribute 和 ToolboxItemFilterType。
其他元数据预配
VSPackage 可以在非设计时更改设计器或设计器组件的配置。
该 ProvideDesignerMetadataAttribute 类可以编程方式使用,也可以应用于提供设计器的 VSPackage。
类的 ProvideDesignerMetadataAttribute 实例用于修改在设计图面上创建的组件的元数据。 例如,可以将对象使用 CommonDialog 的默认属性浏览器替换为自定义属性浏览器。
ProvideDesignerMetadataAttribute提供的实例对VSPackage的Package实现所作的修改可以有以下两个范围之一:
全局 -- 给定组件的所有新实例
本地 - 仅适用于在当前 VSPackage 提供的设计图面上创建的组件的实例。
IsGlobal应用于 VSPackage 实现ProvideDesignerMetadataAttribute的实例的属性Package决定了此范围。
将此属性应用于Package的实现,并将ProvideDesignerMetadataAttribute对象的IsGlobal属性设置为true。如下面所示,这会更改整个 Visual Studio 环境中使用的浏览器。
[ProvideDesignerMetadata(typeof(Color), typeof(CustomBrowser),
IsGlobal=true
)]
internal class MyPackage : Package {}
如果 global 标志设置为 false,则元数据更改对当前 VSPackage 支持的设计器而言是本地的。
[ProvideDesignerMetadata(typeof(Color), typeof(CustomBrowser),
IsGlobal=false
)]
internal class MyPackage : Package {}
注释
设计图面仅支持创建组件,因此只有组件可以具有本地元数据。 在上面的示例中,我们尝试修改属性,例如 Color 对象的属性。 如果将 false 作为全局标志传入,则 CustomBrowser 永远不会出现,因为设计者从未实际创建 Color 的实例。 将全局标志设置为 false 对控件、计时器和对话框等组件非常有用。