提供设计时元数据
[本文档仅供预览,在以后的发行版中可能会发生更改。包含的空白主题用作占位符。]
为 WPF 或 Silverlight 控件创作自定义设计体验即是将它们部署到单独的设计时程序集内。 可以通过创建用元数据特性填充的表,来指定这些自定义设计时实现如何与 Visual Studio 和 Expression Blend 之类的工具进行交互。
设计时程序集
当设计工具(如 Visual Studio)打开自定义控件的程序集时,它还查找相关的设计时程序集。 特别是,设计工具查找 ProvideMetadataAttribute 程序集级特性。 在找到该特性后,设计器会在程序集内搜索实现 IProvideAttributeTable 接口的类。 设计器会在该类的 AttributeTable 属性中查询用来指定设计时行为的特性集合。 有关更多信息,请参见演练:提供自定义设计时元数据和部署自定义控件和设计时程序集。
特性表
AttributeTable 类将设计时元数据特性与 WPF 和 Silverlight 类型关联。 特性表为可设计的类型指定特定的设计时实现。 例如,如果您的控件有自定义的 AdornerPanel,请将 FeatureAttribute 添加到特性表中以指定自定义的 FeatureProvider 实现。
特性表生成器
若要创建特性表,需要先创建 AttributeTableBuilder 类的一个实例。 通过调用 AddCustomAttributes 方法将元数据添加到特性表生成器中。 在完成元数据的添加之后,可以通过调用 CreateTable 方法生成特性表。 特性表生成器方法支持回调委托,因此可将特性表的创建一直推迟到需要时。
下面的代码演示如何使用特性表来指定自定义装饰器实现。
' Container for any general design-time metadata to initialize.
' Designers look for a type in the design-time assembly that
' implements IProvideAttributeTable. If found, designers instantiate
' this class and access its AttributeTable property automatically.
Friend Class Metadata
Implements IProvideAttributeTable
' Accessed by the designer to register any design-time metadata.
Public ReadOnly Property AttributeTable() As AttributeTable _
Implements IProvideAttributeTable.AttributeTable
Get
Dim builder As New AttributeTableBuilder()
' Add the adorner provider to the design-time metadata.
builder.AddCustomAttributes(GetType(ButtonWithDesignTime), _
New FeatureAttribute(GetType(OpacitySliderAdornerProvider)))
Return builder.CreateTable()
End Get
End Property
End Class
// Container for any general design-time metadata to initialize.
// Designers look for a type in the design-time assembly that
// implements IProvideAttributeTable. If found, designers instantiate
// this class and access its AttributeTable property automatically.
internal class Metadata : IProvideAttributeTable
{
// Accessed by the designer to register any design-time metadata.
public AttributeTable AttributeTable
{
get
{
AttributeTableBuilder builder = new AttributeTableBuilder();
// Add the adorner provider to the design-time metadata.
builder.AddCustomAttributes(
typeof(ButtonWithDesignTime),
new FeatureAttribute(typeof(OpacitySliderAdornerProvider)));
return builder.CreateTable();
}
}
}
有关更多信息,请参见演练:创建设计时装饰器。
基本设计时实现工作流
在创作自定义设计体验时,通常遵循相似的工作流。 有关更多信息,请参见如何:部署自定义控件和设计时程序集。
有关演示如何实现自定义设计时体验的示例,请参见 WPF and Silverlight Designer Extensibility Samples(WPF 和 Silverlight 设计器扩展性示例)。
分离设计时程序集的优点
适用于 Visual Studio 的 WPF 设计器框架可用来将设计时元数据与实现分离。 将元数据与控件的运行时代码分离是一个重要的设计原则,原因如下。
一遍一遍地生成以及团队之间的集成逻辑可能会使将元数据编译到控件中变得异常繁琐。
将元数据编译到控件中可防止外部工具(如 WPF Designer或 Expression Blend)在以后修改该元数据。 这是一个事关灵活性的重要问题。 如果不将设计时元数据与控件分离,那么,没有 .NET Framework 的新版本,Visual Studio 就无法确定其设计器的版本。
将元数据编译到控件中会大大增加控件程序集的大小。 设计时特性还会减慢控件的执行速度。 由于内存中加载了其他特性,因此那些使用反射的控件功能(如数据绑定)便会受到影响。
设计时元数据提供设计器的“个性设置”。 设计器的功能大部分绑定到承载它的应用程序(而不是控件)。 WPF Designer和 Expression Blend 使用不同的元数据集来提供面向特定用户类型的功能集。