对与设计器或设计器组件关联的元数据和筛选器属性的操作为应用程序提供了一种机制,用于定义特定设计器使用哪些工具来处理不同的 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 对象的 UITypeEditor,以使用资源管理器获取位图,而不是文件系统。
与环境集成,例如,通过订阅事件或获取项目配置信息。 可以通过获取 ITypeResolutionService 接口来获取项目配置信息并订阅事件。
通过激活适当的工具箱类别或通过将 ToolboxItemFilterAttribute 类的实例应用于设计器来限制设计器的适用性来修改用户环境。
VSPackage 实现设计器初始化
VSPackage 可通过以下方式处理设计器初始化:
创建实现 DesignSurfaceExtension 类的对象。
注意
DesignSurfaceExtension 类不应在与 Package 类相同的对象上实现。
将实现 DesignSurfaceExtension 的类注册为提供对 VSPackage 的设计器扩展的支持。 通过将 DesignSurfaceExtensionAttribute、ProvideObjectAttribute 和 ProvideServiceAttribute 的实例应用于提供 Package 的 VSPackage 实现的类来注册该类。
每当创建设计器或设计器组件时,Visual Studio 环境:
访问每个已注册的设计图面扩展提供程序。
实例化和初始化每个设计图面扩展提供程序的 DesignSurfaceExtension 对象的实例。
调用每个设计图面扩展提供程序的 OnDesignerCreated 方法或 OnComponentCreated 方法(视情况而定)。
当将 DesignSurfaceExtension 对象实现为 VSPackage 的成员时,重要的是要理解:
Visual Studio 环境不提供对特定
DesignSurfaceExtension
提供程序修改的元数据或其他配置设置的任何控制。 两个或多个DesignSurfaceExtension
提供程序可能以冲突的方式修改同一设计器功能,最终修改是决定性的。 最后应用哪种修改尚不确定。通过将 ToolboxItemFilterAttribute 的实例应用于 DesignSurfaceExtension 对象的实现,可以显式地将该实现限制为特定的设计器。 有关工具箱项筛选的详细信息,请参阅 ToolboxItemFilterAttribute 和 ToolboxItemFilterType。
其他元数据预配
VSPackage 可以更改设计时以外的设计器或设计器组件的配置。
ProvideDesignerMetadataAttribute 类可以编程方式使用,也可以应用于提供设计器的 VSPackage。
ProvideDesignerMetadataAttribute 类的实例用于修改在设计图面上创建的组件的元数据。 例如,可以将 CommonDialog 对象使用的默认属性浏览器替换为自定义属性浏览器。
应用于 VSPackage 的 Package 实现的 ProvideDesignerMetadataAttribute 实例提供的修改可以有以下两个范围之一:
全局 -- 针对给定组件的所有新实例
本地 -- 仅适用于在当前 VSPackage 提供的设计图面上创建的组件的实例。
应用于 VSPackage 的 Package 实现的 ProvideDesignerMetadataAttribute 实例的 IsGlobal
属性决定了此范围。
将属性应用于 Package 的实现,并将 ProvideDesignerMetadataAttribute 对象的 IsGlobal 属性设置为 true
,如下所示,将更改整个 Visual Studio 环境的浏览器:
[ProvideDesignerMetadata(typeof(Color), typeof(CustomBrowser),
IsGlobal=true
)]
internal class MyPackage : Package {}
如果全局标志设置为 false
,则元数据更改是当前 VSPackage 支持的当前设计器的本地更改:
[ProvideDesignerMetadata(typeof(Color), typeof(CustomBrowser),
IsGlobal=false
)]
internal class MyPackage : Package {}
注意
设计图面仅支持创建组件,因此只有组件可以具有本地元数据。 在上面的示例中,我们尝试修改属性,例如对象的 Color
属性。 如果为全局标志传入 false
,则 CustomBrowser
永远不会显示,因为设计器从未实际创建 Color
的实例。 将全局标志设置为 false
对控件、计时器和对话框等组件非常有用。