元数据attribute主要分为两大类:
- 设计期attribute
- 解析期attribute
设计期attribute
设计期attribute对于控件在可视化设计器(如.NET 2003)内正确运行是很重要的,设计器、属性浏览器和其他的设计期元素使用设计期attribute提供的元数据的作用如下:
- 显示属性和事件
- 执行设计期的序列化
- 把用来实现设计期功能的类和控件或者属性类型关联起来
因为设计时特性向可视设计工具提供有价值的信息,所以它们对在设计时正确显示控件及其成员非常重要。
在下面的代码片段中,CategoryAttribute特性启用属性浏览器以在“Alignment”类别中显示 TextAlignment
属性。DescriptionAttribute特性允许属性浏览器在用户单击某个属性时显示该属性的简要说明。
1 [C#]
2 [
3 Category("Alignment"),
4 Description("Specifies the alignment of text.")
5 ]
6 public ContentAlignment TextAlignment { }
在 C# 和 Visual Basic .NET 中,名为 AttributeNameAttribute 的特性类在特性语法中可以被简单地引用为 AttributeName。
某些设计时特性是在类级别应用的。DesignerAttribute 特性在类级别应用,它通知窗体设计器使用哪个设计器类来显示控件。组件与默认的设计器 (System.ComponentModel.Design.ComponentDesigner) 关联,Windows 窗体和 ASP.NET 服务器控件与它们自己的默认设计器关联。只有在为组件或控件定义自定义设计器时才应用 DesignerAttribute。
1 [C#]
2 // Associates the designer class SimpleControl.Design.SimpleDesigner
3 // with Simple.
4 [ Designer(typeof(SimpleControl.Design.SimpleDesigner))]
5 public class Simple : WebControl { // }
1.显示属性和事件的attribute
下面的attribute在设计期里用来显示属性和事件。
1)BrowsableAttribute 类
指定一个属性或事件是否应显示在“属性”窗口中。
System.Object
System.Attribute
System.ComponentModel.BrowsableAttribute
概要:告知属性浏览器,是否在属性浏览器中显示属性或事件。
应用:属性和事件
样例中的使用:[Browsable(true)]
参数类型:Boolean
默认值:true
注意:当检查代码中此特性的值时,必须将该特性指定为BrowsableAttribute.Yes 或BrowsableAttribute.No。
示例:下面的示例将属性标记为可浏览。
1 [C#]
2 [Browsable(true)]
3 public int MyProperty
4 {
5 get {
6 // Insert code here.
7 return 0;
8 }
9 set {
10 // Insert code here.
11 }
12 }
下一个示例显示如何检查 MyProperty
的 BrowsableAttribute 的值。
首先,代码获取具有该对象的所有属性的 PropertyDescriptorCollection。
接着,将代码编入 PropertyDescriptorCollection 的索引,以获取 MyProperty
。
然后它返回该属性的特性,并将它们保存到特性变量中。
该示例提供两种不同的方法检查 BrowsableAttribute 的值。
在第二个代码片断中,示例调用 Equals 方法。在最后一个代码段中,该示例使用 Browsable 属性检查此值。
2 // Gets the attributes for the property.
3 AttributeCollection attributes =
4 TypeDescriptor.GetProperties(this)["MyProperty"].Attributes;
5
6 // Checks to see if the value of the BrowsableAttribute is Yes.
7 if(attributes[typeof(BrowsableAttribute)].Equals(BrowsableAttribute.Yes)) {
8 // Insert code here.
9 }
10
11 // This is another way to see whether the property is browsable.
12 BrowsableAttribute myAttribute =
13 (BrowsableAttribute)attributes[typeof(BrowsableAttribute)];
14 if(myAttribute.Browsable) {
15 // Insert code here.
16 }
17
如果将类标记为 BrowsableAttribute,可使用下列代码检查该值。
1 [C#]
2 AttributeCollection attributes =
3 TypeDescriptor.GetAttributes(MyProperty);
4 if(attributes[typeof(BrowsableAttribute)].Equals(BrowsableAttribute.Yes)) {
5 // Insert code here.
6 }
7
2)BindableAttribute 类
指定属性是否通常用于绑定。
System.Object
System.Attribute
System.ComponentModel.BindableAttribute
概要:告知属性浏览器绑定数据到属性是否有意义。
带有Bindable[true]标记的属性能显示在从属性浏览器中装载的DataBinding对话框里,
页面开发者利用它可以把属性和数据绑定表达式关联起来。
应用:只应用于属性
样例中的使用:[Bindable(true)]
参数类型:Boolean
默认值:false
注意:若要在代码中检查该特性的值,必须将该特性指定为 BindableAttribute.Yes 或 BindableAttribute.No。
只能在设计时使用该特性。在运行时可以随意向任何属性进行绑定。
如果属性没有标记为Bindable(true),页面开发者仍能够通过在.aspx页面里手动输入表达式
来把属性和一个数据绑定表达式关联起来。
示例:下面的示例将属性标记为适于将数据绑定到的属性。
1 [C#]
2 [Bindable(true)]
3 public int MyProperty {
4 get {
5 // Insert code here.
6 return 0;
7 }
8 set {
9 // Insert code here.
10 }
11 }
下一个示例显示如何检查 MyProperty
的 BindableAttribute 的值。
首先,代码获取具有该对象的所有属性的 PropertyDescriptorCollection。
接着它使用索引进入 PropertyDescriptorCollection 以获取 MyProperty
。
最后,它返回该属性的特性,并将它们保存在特性变量中。
此示例介绍两种不同的检查 BindableAttribute 的值的方法。
在第二个代码片断中,示例调用 Equals 方法。
在最后一个代码片段中,该示例使用 Bindable 属性检查该值。
1 [C#]
2 // Gets the attributes for the property.
3 AttributeCollection attributes =
4 TypeDescriptor.GetProperties(this)["MyProperty"].Attributes;
5
6 // Checks to see if the value of the BindableAttribute is Yes.
7 if(attributes[typeof(BindableAttribute)].Equals(BindableAttribute.Yes)) {
8 // Insert code here.
9 }
10
11 // This is another way to see whether the property is bindable.
12 BindableAttribute myAttribute =
13 (BindableAttribute)attributes[typeof(BindableAttribute)];
14 if(myAttribute.Bindable) {
15 // Insert code here.
16 }
17
18 // Yet another way to see whether the property is bindable.
19 if (attributes.Contains(BindableAttribute.Yes)) {
20 // Insert code here.
21 }
如果将类标记为 BindableAttribute,则可使用以下代码检查该值。
2 AttributeCollection attributes =
3 TypeDescriptor.GetAttributes(MyProperty);
4 if(attributes[typeof(BindableAttribute)].Equals(BindableAttribute.Yes)) {
5 // Insert code here.
6 }
3)CategoryAttribute 类
指定其属性或事件将显示在可视化设计器中的类别。
System.Object
System.Attribute
System.ComponentModel.CategoryAttribute
概要:提供一个分类名,以这个分类名来显示属性或事件。
这个attribute允许属性浏览器以逻辑分组的形式显示属性和事件。
应用:属性和事件
样例中的使用:[Category("Appearance")]
参数类型:string
默认值:"Default"
注意:CategoryAttribute 指示在一个被设置为按分类顺序模式的
System.Windows.Forms.PropertyGrid 控件中列出属性或事件时,
将关联的属性或事件与之关联的类别。
如果没有对属性或事件应用 CategoryAttribute,
则 System.Windows.Forms.PropertyGrid 将属性或事件与杂项类别关联。
通过在 CategoryAttribute 的构造函数中指定类别的名称,
可以为任何名称创建新的类别。
Category 属性指示该属性所代表的类别的名称。
Category 属性还以透明方式对类别名称进行本地化。
这个attribute可以被局部化。
对继承者的说明:如果使用类别名称而不是预定义的名称,
并且想要本地化类别名称,
则必须重写 GetLocalizedString 方法。
此外,可以重写 Category 属性以提供您自己的本地化逻辑。
CategoryAttribute 类定义下列通用类别:
类别 | 说明 |
---|---|
Action | 与可用操作相关的属性。 |
Appearance | 与实体的外观相关的属性。 |
Behavior | 与实体的行为相关的属性。 |
Data | 与数据和数据源管理相关的属性。 |
Default | 组合到默认类别中的属性。 |
Design | 仅在设计时可用的属性。 |
DragDrop | 与拖放操作相关的属性。 |
Focus | 与焦点相关的属性。 |
Format | 与格式设置相关的属性。 |
Key | 与键盘相关的属性。 |
Layout | 与布局相关的属性。 |
Mouse | 与鼠标相关的属性。 |
WindowStyle | 与顶级窗体的窗口样式相关的属性。 |
示例:下面的示例创建 MyImage 属性。
2 [Category("Appearance")]
3 public Image MyImage {
4 get {
5 // Insert code here.
6 return image1;
7 }
8 set {
9 // Insert code here.
10 }
11 }
下一个示例获取 MyImage
的类别。
首先,代码获取具有该对象的所有属性的 PropertyDescriptorCollection。
接着,将代码编入 PropertyDescriptorCollection 的索引,
以获取 MyImage
。然后它返回该属性的特性,并将它们保存到 attributes
变量中。
然后,该示例通过以下方法输出类别:
从 AttributeCollection 检索 CategoryAttribute,然后将它写到控制台屏幕上。
2 // Gets the attributes for the property.
3 AttributeCollection attributes =
4 TypeDescriptor.GetProperties(this)["MyImage"].Attributes;
5
6 // Prints the description by retrieving the CategoryAttribute.
7 // from the AttributeCollection.
8 CategoryAttribute myAttribute =
9 (CategoryAttribute)attributes[typeof(CategoryAttribute)];
10 Console.WriteLine(myAttribute.Category);
4)DefaultEventAttribute 类
指定组件的默认事件。
System.Object
System.Attribute
System.ComponentModel.DefaultEventAttribute
概要:告诉属性浏览器哪一个控件事件是默认事件。
允许页面开发者双击设计界面中的控件,为默认事件编写事件处理代码。
应用:只应用于事件
样例中的使用:[DefaultEvent("Click")]
参数类型:string
默认值:无
示例:以下示例定义名为 MyCollection
的集合类。
该类标记为 DefaultEventAttribute,它指定 CollectionChanged
作为默认事件。
2 [DefaultEvent("CollectionChanged")]
3 public class MyCollection : BaseCollection {
4
5 private CollectionChangeEventHandler onCollectionChanged;
6
7 public event CollectionChangeEventHandler CollectionChanged {
8 add {
9 onCollectionChanged += value;
10 }
11 remove {
12 onCollectionChanged -= value;
13 }
14 }
15 // Insert additional code.
16 }
下一个示例创建 MyCollection
的实例。
然后它获取该类的特性,提取 DefaultEventAttribute,并输出默认事件的名称。
2 public static int Main() {
3 // Creates a new collection.
4 MyCollection myNewCollection = new MyCollection();
5
6 // Gets the attributes for the collection.
7 AttributeCollection attributes = TypeDescriptor.GetAttributes(myNewCollection);
8
9 /* Prints the name of the default event by retrieving the
10 * DefaultEventAttribute from the AttributeCollection. */
11 DefaultEventAttribute myAttribute =
12 (DefaultEventAttribute)attributes[typeof(DefaultEventAttribute)];
13 Console.WriteLine("The default event is: " + myAttribute.Name);
14 return 0;
15 }
指定组件的默认属性。
System.Object
System.Attribute
System.ComponentModel.DefaultPropertyAttribute
概要:告诉属性浏览器哪一个控件属性是默认属性。
页面开发者在设计界面中选择控件时,该属性被属性浏览器突出显示。
应用:只应用于属性
样例中的使用:[DefaultProperty("MyProperty")]
参数类型:string
默认值:无
示例:以下示例定义名为
MyControl
的控件。 该类标记为 DefaultPropertyAttribute,它指定
MyProperty
作为默认属性。 2 [DefaultProperty("MyProperty")]
3 public class MyControl : Control {
4 public int MyProperty {
5 get {
6 // Insert code here.
7 return 0;
8 }
9 set {
10 // Insert code here.
11 }
12 }
13 // Insert any additional code.
14 }
下一个示例创建 MyControl
的实例。
然后它获取该类的特性,提取 DefaultPropertyAttribute,并输出默认属性的名称。
2 public static int Main() {
3 // Creates a new control.
4 MyControl myNewControl = new MyControl();
5
6 // Gets the attributes for the collection.
7 AttributeCollection attributes = TypeDescriptor.GetAttributes(myNewControl);
8
9 /* Prints the name of the default property by retrieving the
10 * DefaultPropertyAttribute from the AttributeCollection. */
11 DefaultPropertyAttribute myAttribute =
12 (DefaultPropertyAttribute)attributes[typeof(DefaultPropertyAttribute)];
13 Console.WriteLine("The default property is: " + myAttribute.Name);
14
15 return 0;
16 }
6)DescriptionAttribute 类
指定属性或事件的说明。
System.Object
System.Attribute
System.ComponentModel.DescriptionAttribute
概要:提供一个简要的描述,在用户选择了属性或事件时,属性浏览器就显示这个描述。
应用:属性和事件
样例中的使用:[Description("The image associated with the control")]
参数类型:string
默认值:无
注意:可视化设计器在引用组件成员时可以显示指定的说明,
如在“属性”窗口中。调用 Description 访问该特性的值。
这个attribute可以被局部化。
示例:下面的示例创建 MyImage
属性。
2 [Description("The image associated with the control"),Category("Appearance")]
3 public Image MyImage {
4 get {
5 // Insert code here.
6 return image1;
7 }
8 set {
9 // Insert code here.
10 }
11 }
下一个示例获取 MyImage
的说明。
首先,代码获取具有该对象的所有属性的 PropertyDescriptorCollection。
接着,将它编入 PropertyDescriptorCollection 的索引,
以获取 MyImage
。然后它返回该属性的特性,并将它们保存到特性变量中。
然后该示例通过以下方法输出说明:
从 AttributeCollection 检索 DescriptionAttribute,然后将它写到控制台屏幕上。
2 // Gets the attributes for the property.
3 AttributeCollection attributes =
4 TypeDescriptor.GetProperties(this)["MyImage"].Attributes;
5
6 /* Prints the description by retrieving the DescriptionAttribute
7 * from the AttributeCollection. */
8 DescriptionAttribute myAttribute =
9 (DescriptionAttribute)attributes[typeof(DescriptionAttribute)];
10 Console.WriteLine(myAttribute.Description);
7)EditorBrowsableAttribute 类
指定某个属性或方法在编辑器中可以查看。不能继承此类。
System.Object
System.Attribute
System.ComponentModel.EditorBrowsableAttribute
概要:告知代码编辑器是否为属性、方法或事件显示对IntelliSense的支持。
应用:属性、方法和事件
样例中的使用:[EditorBrowsable(EditorBrowsableState.Never)]
参数类型:EditorBrowsableState的枚举类型
默认值:EditorBrowsableState.Always
注意:可以在可视化设计器或文本编辑器中使用该类来确定用户可见的内容。
例如,Visual Studio .NET 中的智能感知引擎使用此特性来确定是否显示方法或属性。
代码编辑器默认地显示对IntelliSense的支持,仅当想重载默认行为时才应用这个attribute。
EditorBrowsableState枚举成员如下:
成员名称 | 说明 |
---|---|
Advanced | 该属性或方法是只有高级用户才可以看到的功能。编辑器可以显示或隐藏这些属性。 |
Always | 该属性或方法在编辑器中始终是可浏览的。 |
Never | 该属性或方法始终不能在编辑器中浏览。 |
示例:下面的示例说明如何通过为 EditorBrowsableAttribute 特性设置适当的值来向智能感知隐藏控件的属性。
在打开新应用程序,添加对控件的引用,并且声明该控件的实例之后,
IntelliSense 不在下拉列表框中显示 Age
属性。
2 int ageval;
3 [EditorBrowsable(EditorBrowsableState.Never)]
4 public int Age
5 {
6 get { return ageval; }
7 set
8 {
9 if (!ageval.Equals(value))
10 {
11 ageval = value;
12 }
13 }
14 }
15
2.用于设计期序列化的attribute
下面的attribute告知设计器如何去序列化控件及控件的属性。序列化是在页面中对应于设计视图中的更改生成HTML的过程。
1)DefaultValueAttribute 类
指定属性的默认值。
System.Object
System.Attribute
System.ComponentModel.DefaultValueAttribute
概要:为属性提供一个默认值。
应用:属性
样例中的使用:[DefaultValue("Edit Text")]
参数类型:任何的原始类型、枚举类型或字符串文字类型。根据attribute的标记为复杂属性提供默认值。
默认值:无
注意:如果属性的类型具有一个相关联的转换器,就可以为复杂属性提供一个默认值。
在这种情况下,必须采用attribute的两参数形式,形式中第一参数规定了属性的类型,
第二参数规定了这个值的字符串表示,例如:[DefaultValue(typeof(Color),"Red")]。
可以使用任何值创建 DefaultValueAttribute。成员的默认值通常是其初始值。
可视化设计器可以使用默认值重置成员的值。代码生成器也可使用默认值确定是否为成员生成代码。
示例:以下示例将
MyProperty
的默认值设置为 false。 2
3 private bool myVal=false;
4
5 [DefaultValue(false)]
6 public bool MyProperty {
7 get {
8 return myVal;
9 }
10 set {
11 myVal=value;
12 }
13 }
下一个示例检查
MyProperty
的默认值。 首先,代码获取具有该对象的所有属性的 PropertyDescriptorCollection。
接着,将它编入 PropertyDescriptorCollection 的索引,以获取
MyProperty
。 然后它返回该属性的特性,并将它们保存到特性变量中。
接着该示例通过从 AttributeCollection 检索 DefaultValueAttribute 来打印默认值,并将其名称写到控制台屏幕。
2 // Gets the attributes for the property.
3 AttributeCollection attributes =
4 TypeDescriptor.GetProperties(this)["MyProperty"].Attributes;
5
6 /* Prints the default value by retrieving the DefaultValueAttribute
7 * from the AttributeCollection. */
8 DefaultValueAttribute myAttribute =
9 (DefaultValueAttribute)attributes[typeof(DefaultValueAttribute)];
10 Console.WriteLine("The default value is: " + myAttribute.Value.ToString());
2)DesignerSerializationVisibilityAttribute 类
指定在设计时序列化组件上的属性时所使用的持久性类型。
System.Object
System.Attribute
System.ComponentModel.DesignerSerializationVisibilityAttribute
概要:告诉设计器是否序列化属性或属性的内容。 复杂属性含有内容-比如子属性或者集合项
应用:属性
样例中的使用:[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
参数类型:DesignerSerializationVisibility的枚举类型:
Content,指定序列化程序应该序列化属性的内容,而不是属性本身。此字段为只读。
Hidden,指定序列化程序不应该序列化属性的值。此静态(在 Visual Basic 中为 Shared)字段是只读的。
Visible,指定应该允许序列化程序序列化属性的值。此静态(在 Visual Basic 中为 Shared)字段是只读的。
默认值:DesignerSerializationVisibility.Visible
注意:默认情况下,代码生成器序列化属性值。attribute允许重载默认行为,排除序列化机制中的属性,
或者序列化属性的内容(例如子属性或者集合项)而不是属性自身。
当序列化程序保持设计模式文档的可持续状态时,它通常会向组件的初始化方法中添加代码,
以便保持已在设计时设置的属性值。如果尚未设置指示其他行为的特性,大多数基类型都会默认出现此情况。
DesignerSerializationVisibilityAttribute 允许您指示属性值是否为 Visible,
是否应在初始化代码中保持,Hidden,是否不应在初始化代码中保持,
是否由 Content 组成,它应具有为分配到该属性的对象的每个公共属性(而非隐藏属性)生成的初始化代码。
没有 DesignerSerializationVisibilityAttribute 的成员将被视为
具有值为 Visible 的 DesignerSerializationVisibilityAttribute。
如果可能,序列化程序会将标记为 Visible 的属性值序列化为该类型。
要为特定类型或属性指定自定义序列化,请使用 DesignerSerializerAttribute。
示例:下面的示例说明如何使用设置为 Content 的 DesignerSerializationVisibilityAttribute,
以保持可在设计时配置的用户控件的公共属性值。
要使用该示例,请先将以下代码编译到用户控件库中。
下一步,将新项目中的引用添加到已编译的 .DLL 文件,右击工具箱并选择“自定义工具箱...”,
然后从包含用户控件的 .DLL 文件选择控件,从而在设计模式下将 .DLL 文件中的控件添加到“工具箱”。
接着,将控件从工具箱拖动到“窗体”中,然后设置选中控件时属性网格中列出的 DimensionData 对象的属性。
查看窗体代码时,代码应已添加到控件父窗体的 InitializeComponent 方法中,
该方法将控件的属性值设置为您在设计模式下设置的值。
2 using System;
3 using System.Collections;
4 using System.ComponentModel;
5 using System.ComponentModel.Design;
6 using System.Drawing;
7 using System.Windows.Forms;
8
9 namespace DesignerSerializationVisibilityTest
10 {
11 /* The code for this user control declares a public property of type DimensionData with a DesignerSerializationVisibility
12 attribute set to DesignerSerializationVisibility.Content, indicating that the properties of the object should be serialized.
13
14 The public, not hidden properties of the object that are set at design time will be persisted in the initialization code
15 for the class object. Content persistence will not work for structs without a custom TypeConverter.*/
16 public class ContentSerializationExampleControl : System.Windows.Forms.UserControl
17 {
18 private System.ComponentModel.Container components = null;
19
20 [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
21 public DimensionData Dimensions
22 {
23 get
24 {
25 return new DimensionData(this);
26 }
27 }
28
29 public ContentSerializationExampleControl()
30 {
31 InitializeComponent();
32 }
33
34 protected override void Dispose( bool disposing )
35 {
36 if( disposing )
37 {
38 if( components != null )
39 components.Dispose();
40 }
41 base.Dispose( disposing );
42 }
43
44 private void InitializeComponent()
45 {
46 components = new System.ComponentModel.Container();
47 }
48 }
49
50 [TypeConverterAttribute(typeof(System.ComponentModel.ExpandableObjectConverter))]
51 /*This attribute indicates that the public properties of this object should be listed in the property grid.*/
52 public class DimensionData
53 {
54 private Control owner;
55
56 /*This class reads and writes the Location and Size properties from the Control which it is initialized to.*/
57 internal DimensionData(Control owner)
58 {
59 this.owner = owner;
60 }
61
62 public Point Location
63 {
64 get
65 {
66 return owner.Location;
67 }
68 set
69 {
70 owner.Location = value;
71 }
72 }
73
74 public Size FormSize
75 {
76 get
77 {
78 return owner.Size;
79 }
80 set
81 {
82 owner.Size = value;
83 }
84 }
85 }
86 }
3)NotifyParentPropertyAttribute 类
指示当此属性应用到的属性的值被修改时将通知父属性。不能继承此类。
System.Object
System.Attribute
System.ComponentModel.NotifyParentPropertyAttribute
概要:告知属性浏览器从子属性到父属性或者到控件上传一个更改通知。
应用:复杂属性和它们的子属性
样例中的使用:[NotifyParentPropertyAttribute(true)]
参数类型:Boolean
默认值:false
注意:如果属性的父属性应该在该属性值更改时接到通知,则向该属性应用 NotifyParentPropertyAttribute。
例如,Size 属性具有两个嵌套的属性:高度和宽度。
这些嵌套的属性应标记为 NotifyParentPropertyAttribute(true),以便当属性值更改时,
它们可以通知父属性来更新其值并显示。
4)PersistChildrenAttribute 类
定义 ASP.NET 服务器控件使用的元数据属性。该属性指示设计时是否应将 ASP.NET 服务器控件的子控件作为嵌套内部控件保持。无法继承此类。
System.Object
System.Attribute
System.Web.UI.PersistChildrenAttribute
概要:告知设计器嵌套在控件标签内的内容是否和子控件或者属性对应。
应用:控件
样例中的使用:[PersistChildren(false)]
参数类型:Boolean
默认值:值为true意味着嵌套的内容对应子控件
注意:WebControl标记为PersistChildren(false)。如果控件派生于WebControl,
仅当实现的控件的嵌套内容对应于子控件时,才需要重新应用这个attribute。
如果该属性为 true,则将 ASP.NET 服务器控件的子控件作为嵌套服务器控件标记保持。
如果为 false,则将该控件的属性作为嵌套元素保持。
示例:
2 using System.Collections;
3 using System.Drawing;
4 using System.Web;
5 using System.Web.UI;
6 using System.Web.UI.WebControls;
7
8 namespace PersistChildrenSamples
9 {
10 // The child element class.
11 public class Employee
12 {
13 private String name;
14 private String title;
15 private String alias;
16
17 public Employee():this ("","",""){}
18
19 public Employee (String name, String title, String alias)
20 {
21 this.name = name;
22 this.title = title;
23 this.alias = alias;
24 }
25 public String Name
26 {
27 get
28 {
29 return name;
30 }
31 set
32 {
33 name = value;
34 }
35 }
36
37 public String Title
38 {
39 get
40 {
41 return title;
42 }
43 set
44 {
45 title = value;
46 }
47 }
48
49 public String Alias
50 {
51 get
52 {
53 return alias;
54 }
55 set
56 {
57 alias = value;
58 }
59 }
60 }
61 // Use the PersistChildren attribute to set the Persist
62 // property to false so that none of this class's
63 // child controls will be persisted as controls. They will
64 // be persisted only as child elements of this class.
65 // If you set the PersistChildren attribute to true, or if you
66 // do not include this attribute when you create a control,
67 // the child controls will be persisted as controls.
68 [PersistChildren(false)]
69 public class CollectionPropertyControl : Control
70 {
71 private String header;
72 private ArrayList employees = new ArrayList();
73
74 public String Header
75 {
76 get
77 {
78 return header;
79 }
80 set
81 {
82 header = value;
83 }
84 }
85
86
87
88 public ArrayList Employees
89 {
90 get
91 {
92 return employees;
93 }
94 }
95 // Override the CreateChildControls method to
96 // add child controls to the Employees property when this
97 // custom control is requested from a page.
98 protected override void CreateChildControls()
99 {
100 Label label = new Label();
101 label.Text = Header;
102 label.BackColor = Color.Beige;
103 label.ForeColor = Color.Red;
104 Controls.Add(label);
105 Controls.Add(new LiteralControl("<BR> <BR>"));
106
107 Table table = new Table();
108 TableRow htr = new TableRow();
109
110 TableHeaderCell hcell1 = new TableHeaderCell();
111 hcell1.Text = "Name";
112 htr.Cells.Add(hcell1);
113
114 TableHeaderCell hcell2 = new TableHeaderCell();
115 hcell2.Text = "Title";
116 htr.Cells.Add(hcell2);
117
118 TableHeaderCell hcell3 = new TableHeaderCell();
119 hcell3.Text = "Alias";
120 htr.Cells.Add(hcell3);
121 table.Rows.Add(htr);
122
123 table.BorderWidth = 2;
124 table.BackColor = Color.Beige;
125 table.ForeColor = Color.Red;
126 foreach (Employee employee in Employees)
127 {
128 TableRow tr = new TableRow();
129
130 TableCell cell1 = new TableCell();
131 cell1.Text = employee.Name;
132 tr.Cells.Add(cell1);
133
134 TableCell cell2 = new TableCell();
135 cell2.Text = employee.Title;
136 tr.Cells.Add(cell2);
137
138 TableCell cell3 = new TableCell();
139 cell3.Text = employee.Alias;
140 tr.Cells.Add(cell3);
141
142 table.Rows.Add(tr);
143 }
144 Controls.Add(table);
145
146 }
147 }
148 }
5)PersistenceModeAttribute 类
定义指定如何将 ASP.NET 服务器控件属性或事件保持到 ASP.NET 页的元数据属性。无法继承此类。
System.Object
System.Attribute
System.Web.UI.PersistenceModeAttribute
概要:告知设计器是否把属性保存到控件的标签上,或者把它作为一个嵌套属性进行保存。
应用:属性
样例中的使用:[PersistenceMode(PersistenceMode.InnerProperty)]
参数类型:PersistenceMode枚举类型
成员名称 | 说明 |
---|---|
Attribute | 指定属性或事件保持为特性。 |
EncodedInnerDefaultProperty | 指定属性作为 ASP.NET 服务器控件的唯一内部文本而进行保持。属性值是 HTML 编码的。只能对字符串做这种指定。 |
InnerDefaultProperty | 指定属性在 ASP.NET 服务器控件中保持为内部文本。还指示将该属性定义为元素的默认属性。只能指定一个属性为默认属性。 |
InnerProperty | 指定属性在 ASP.NET 服务器控件中保持为嵌套标记。这通常用于复杂对象;它们具有自己的持久性属性。 |
示例:
2 [PersistenceMode(PersistenceMode.InnerProperty),
3 TemplateContainer(typeof(TemplateItem))]
4 public ITemplate MessageTemplate {
5 get {
6 return _messageTemplate;
7 }
8 set {
9 _messageTemplate = value;
10 }
11 }
6)TagPrefixAttribute 类
定义在 Web 页中用于标识自定义控件的标记前缀。无法继承此类。
System.Object
System.Attribute
System.Web.UI.TagPrefixAttribute
概要:告知设计器生成一个Register指令,把一个标签前缀映射到命名控件和配件中。
当页面开发者把控件从工具箱拖放到设计界面时,这个指令就在.aspx页面中生成。
应用:包含有服务器控件的配件
样例中的使用:[assembly:TagPrefix("CustomControls", "custom")]
参数类型:第一个参数指定了命名空间,第二个参数允许为配件中的控件指定一个标签前缀。
注意:Register指令仅当页面开发者把控件从工具箱拖放到设计界面时才生成。
如果页面开发者手工为页面中的控件添加HTML,指令不会生成。
TagPrefixAttribute 定义为自定义控件指定标记前缀别名所需的程序集级属性。
此属性由 Visual Studio .NET 等工具用来在使用自定义控件的 ASP.NET 页中自动生成 Register 指令。
此指令向命名空间注册标记前缀。而且,它指定自定义控件代码实现所在的程序集。
有了此指令后,就可以在 Web 页中以声明方式使用自定义控件。
示例:
2 using System;
3 using System.Web;
4 using System.Web.UI;
5 using System.Web.UI.WebControls;
6
7 [assembly:TagPrefix("CustomControls", "custom")]
8
9 namespace CustomControls
10 {
11 // Simple custom control
12 public class MyCS_Control : Control
13 {
14 private String message = "Hello";
15
16 public virtual String Message
17 {
18 get
19 {
20 return message;
21 }
22 set
23 {
24 message = value;
25 }
26 }
27
28 [System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name="FullTrust")]
29 protected override void Render( HtmlTextWriter writer)
30 {
31 writer.Write("<span style='background-color:aqua; font:8pt tahoma, verdana;'> "
32 + this.Message + "<br>" + "C# version. The time on the server is " + System.DateTime.Now.ToLongTimeString()
33 + "</span>");
34 }
35 }
36 }
3.提供高级设计期功能的相关联类的attribute
下列attribute使得可以将提供高级设计期功能的类与控件相关联。
1)DesignerAttribute 类
指定用于为组件实现设计时服务的类。
System.Object
System.Attribute
System.ComponentModel.DesignerAttribute
概要:把设计器与控件关联。
应用:控件
样例中的使用:[Designer(typeof (ControlDesigner))]
注意:当设计器和控件位于不同配件时,后期绑定类型是必要的。
用于设计时服务的类必须实现 IDesigner 接口。
使用 DesignerBaseTypeName 属性查找设计器的基类。使用 DesignerTypeName 属性获取与该成员关联的设计器的类型名称。
示例:下面的示例创建一个名为
MyForm
的类。MyForm
具有两项属性,其中一项为 DesignerAttribute,它指定此类使用 DocumentDesigner,另一项为 DesignerCategoryAttribute,它指定 Form 类别。
2 typeof(IRootDesigner)),
3 DesignerCategory("Form")]
4 public class MyForm : ContainerControl {
5 // Insert code here.
6 }
下一个示例创建
MyForm
的实例。然后它获取该类的特性,提取 DesignerAttribute,并输出设计器的名称。2 public static int Main() {
3 // Creates a new form.
4 MyForm myNewForm = new MyForm();
5
6 // Gets the attributes for the collection.
7 AttributeCollection attributes = TypeDescriptor.GetAttributes(myNewForm);
8
9 /* Prints the name of the designer by retrieving the DesignerAttribute
10 * from the AttributeCollection. */
11 DesignerAttribute myAttribute =
12 (DesignerAttribute)attributes[typeof(DesignerAttribute)];
13 Console.WriteLine("The designer for this class is: " + myAttribute.DesignerTypeName);
14
15 return 0;
16 }
2)EditorAttribute 类
指定用来更改属性的编辑器。无法继承此类。
System.Object
System.Attribute
System.ComponentModel.EditorAttribute
概要:把一个用户界面(UI)编辑器与类型或属性相关联,也把一个组件编辑器与一个控件相关联。
应用:类或属性
样例中的使用:[Editor(typeof(StringEditor),typeof(UITypeEditor))]
或者 [Editor(typeof(MyLabelComponentEditor),typeof(ComponentEditor))]
注意:第一个参数是编辑器的类型,第二个参数是编辑器的基类型。
当编辑器和类型(或控件)位于不同配件时,后期绑定类型是必要的。
示例:下面的示例创建
MyImage
类。该类标有 EditorAttribute,它将 ImageEditor 指定为其编辑器。2 [Editor("System.Windows.Forms.ImageEditorIndex, System.Design",
3 typeof(UITypeEditor))]
4 public class MyImage
5 {
6 // Insert code here.
7 }
下一个示例创建
MyImage
类的实例。然后,它获取该类的特性,并输出 myNewImage
使用的编辑器的名称。2 public static int Main() {
3 // Creates a new component.
4 MyImage myNewImage = new MyImage();
5
6 // Gets the attributes for the component.
7 AttributeCollection attributes = TypeDescriptor.GetAttributes(myNewImage);
8
9 /* Prints the name of the editor by retrieving the EditorAttribute
10 * from the AttributeCollection. */
11
12 EditorAttribute myAttribute = (EditorAttribute)attributes[typeof(EditorAttribute)];
13 Console.WriteLine("The editor for this class is: " + myAttribute.EditorTypeName);
14
15 return 0;
16 }
3)TypeConverterAttribute 类
指定用作此特性所绑定到的对象的转换器的类型。无法继承此类。
System.Object
System.Attribute
System.ComponentModel.TypeConverterAttribute
概要:把一个类型转换器与类型或属性关联
应用:类或属性
样例中的使用:[TypeConverter(typeof(MyClassConverter))]
注意:当类型转换器和类型(或控件)位于不同配件时,后期绑定类型是必要的。
用于转换的类必须从 TypeConverter 继承。
使用 ConverterTypeName 属性来获取为该特性所绑定到的对象提供数据转换的类名。
示例:以下示例通知
MyClass
使用名为 MyClassConverter
的类型转换器。此示例假定已在其他地方实现了 MyClassConverter
。实现转换器 (MyClassConverter
) 的类必须从 TypeConverter 类继承。2 [TypeConverter(typeof(MyClassConverter))]
3 public class MyClass {
4 // Insert code here.
5 }
下一个示例创建
MyClass
的实例。然后,它获取该类的特性,并输出 MyClass
所用类型转换器的名称。2 public static int Main() {
3 // Creates a new instance of MyClass.
4 MyClass myNewClass = new MyClass();
5
6 // Gets the attributes for the instance.
7 AttributeCollection attributes = TypeDescriptor.GetAttributes(myNewClass);
8
9 /* Prints the name of the type converter by retrieving the
10 * TypeConverterAttribute from the AttributeCollection. */
11 TypeConverterAttribute myAttribute =
12 (TypeConverterAttribute)attributes[typeof(TypeConverterAttribute)];
13
14 Console.WriteLine("The type conveter for this class is: " +
15 myAttribute.ConverterTypeName);
16
17 return 0;
18 }
解析期attribute
下列attribute被页面解析器用来解析.aspx的语法,为相应页面中的类生成代码。
1)ControlBuilderAttribute 类
指定用于在 ASP.NET 分析器内生成自定义控件的 ControlBuilder 类。无法继承此类。
System.Object
System.Attribute
System.Web.UI.ControlBuilderAttribute
概要:将控件与自定义的控件生成器相关联。
应用:控件
样例中的使用:[ControlBuilderAttribute(typeof(CustomParseControlBuilder))]
注意:ControlBuilder类与基类Control相关联,因此也和每个服务器控件相关联。仅当想把自定义控件生成器和控件相关联时,才应用ControlBuilderAttribute。
示例:下面创建一个自定义选择列表,它用于基于在运行时定义的
SelectedIndex
和 Message
值显示消息。下面的命令行用于生成可执行文件。csc /t:library /out:myWebAppPath/bin/cs_MyControlBuilderAtt.dll ControlBuilderAtt.cs
1 [C#]
2
3 /* File name: controlBuilderAttribute.cs. */
4
5 using System;
6 using System.Web;
7 using System.Web.UI;
8 using System.Web.UI.WebControls;
9 using System.Collections;
10
11
12 namespace CustomControls
13
14 {
15 public class MyCS_Item : Control
16 /* Class name: MyCS_Item.
17 * Defines the child control class.
18 */
19 {
20
21 private String _message;
22
23 public String Message
24 {
25 get
26 {
27 return _message;
28 }
29 set
30 {
31 _message = value;
32 }
33 }
34 }
35
36
37 public class CustomParseControlBuilder : ControlBuilder
38 /* Class name: CustomParserControlBuilder.
39 * Defines the functions and data to be used in building custom controls.
40 * This class is referenced using the ControlBuilderAttribute class. See class below.
41 */
42 {
43 [System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name="FullTrust")]
44 public override Type GetChildControlType(String tagName, IDictionary attributes)
45 {
46 if (String.Compare(tagName, "customitem", true) == 0)
47 {
48 return typeof(MyCS_Item);
49 }
50 return null;
51 }
52 }
53
54
55 [
56 ControlBuilderAttribute(typeof(CustomParseControlBuilder))
57 ]
58 public class MyCS_CustomParse : Control
59 /* Class name: MyCS_CustomParse.
60 * Performs custom parsing of a MyCS_CustomParse control type
61 * child control.
62 * If the child control is of the allowed type, it is added to an
63 * array list. This list is accessed, using the container control attribute
64 * SelectedIndex, to obtain the related child control Message attribute to be displayed.
65 */
66 {
67
68 private ArrayList _items = new ArrayList();
69 private int _selectedIndex = 0;
70
71 public int SelectedIndex
72 {
73 get
74 {
75 return _selectedIndex;
76 }
77 set
78 {
79 _selectedIndex = value;
80 }
81 }
82
83 [System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name="FullTrust")]
84 protected override void AddParsedSubObject(Object obj)
85 /* Function name: AddParsedSubObject.
86 * Updates the array list with the allowed child objects.
87 * This function is called during the parsing of the child controls and
88 * after the GetChildControlType function defined in the associated control
89 * builder class.
90 */
91 {
92 if (obj is MyCS_Item)
93 {
94 _items.Add(obj);
95 }
96 }
97
98 [System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name="FullTrust")]
99 protected override void Render(HtmlTextWriter output)
100 /* Function name: Render.
101 * Establishes the rules to render the built control. In this case, a message is
102 * rendered that is a function of the parent control SelectedIndex attribute and
103 * the related child Message attribute.
104 */
105 {
106 if (SelectedIndex < _items.Count)
107 {
108 output.Write("<span style='background-color:aqua; color:red; font:8pt tahoma, verdana;'><b>" +
109 ((MyCS_Item) _items[SelectedIndex]).Message + "</b></span>" );
110 }
111 }
112 }
113 }
下面的示例使用上面定义的自定义控件。尤其是,它在运行时分配 SelectedIndex
和 Message
值来确定要呈现的消息。请注意,在 Register 指令中显示的值反映上一个命令行。
2 <%@ Register TagPrefix="custom" Assembly="myControlBuilderAtt" Namespace="CustomControls" %>
3 <h4>Using ControlBuilderAttribute Class<h4>
4 <form runat="server">
5 <custom:MyCS_CustomParse SelectedIndex="2" runat=server>
6 <customitem Message="C# version. Item One selected"/>
7 <customitem Message="C# version. Item Two selected"/>
8 <customitem Message="C# version. Item Three selected"/>
9 <customitem Message="C# version. Item Four selected"/>
10 </custom:MyCS_CustomParse>
11 </form>
2)ParseChildrenAttribute 类
定义可在开发 ASP.NET 服务器控件时使用的元数据属性。使用它可以指示当在页上以声明方式使用控件时,嵌套在服务器控件标记内的 XML 元素是应视为属性还是应视为子控件。无法继承此类。
System.Object
System.Attribute
System.Web.UI.ParseChildrenAttribute
概要:通知解析器是否把控件内的嵌套内容翻译为属性或者子控件。
应用:控件
样例中的使用:[ParseChildren(true, "Employees")] 或者 [ParseChildren(true)]
注意:构造器接收一个Boolean值,指示解析器是否把嵌套内容解析为属性。
Control没有标记这个attribute,就意味着解析器把嵌套内容当作控件。
WebControl标记为ParseChildren(true),因此解析器把嵌套内容当作属性。
可以通过重新把这个attribute应用到控件来重载和基类有关联的解析逻辑。
这个attribute的两个参数形式中的第二个是属性名,使用两个参数形式时,控件标签内的嵌套内容必须和第二个参数设定的属性一致。
当 String 传递到该类的构造函数中时,它定义父服务器控件的默认属性。
示例:
2 // When compiling this class, name it ParseChildren.dll.
3 // Create a namespace that defines two classes: one is a custom control
4 // named Employee, which is created for every instance of a child
5 // element with its name declared in a page associated with this namespace,
6 // and the other, named Employees, that contains these child elements.
7 using System;
8 using System.Collections;
9 using System.Web;
10 using System.Web.UI;
11 using System.Web.UI.WebControls;
12
13 namespace ParseChildrenSamples
14 {
15 // The child element class.
16 public class Employee
17 {
18 private String name;
19 private String title;
20 private String alias;
21
22 public Employee():this ("","",""){}
23
24 public Employee (String name, String title, String alias)
25 {
26 this.name = name;
27 this.title = title;
28 this.alias = alias;
29 }
30 public String Name
31 {
32 get
33 {
34 return name;
35 }
36 set
37 {
38 name = value;
39 }
40 }
41
42 public String Title
43 {
44 get
45 {
46 return title;
47 }
48 set
49 {
50 title = value;
51 }
52 }
53
54 public String Alias
55 {
56 get
57 {
58 return alias;
59 }
60 set
61 {
62 alias = value;
63 }
64 }
65 }
66 // Use the ParseChildren attribute to set the ChildrenAsProperties
67 // and DefaultProperty properties. Using this constructor, the
68 // control parses all child controls as properties and must define
69 // a public property named Employees, which it declares as
70 // an ArrayList. Nested (child) elements must correspond to
71 // child elements of the Employees property or to other
72 // properties of the control.
73 [ParseChildren(true, "Employees")]
74 public class CollectionPropertyControl : Control
75 {
76 private String header;
77 private ArrayList employees = new ArrayList();
78
79 public String Header
80 {
81 get
82 {
83 return header;
84 }
85 set
86 {
87 header = value;
88 }
89 }
90
91
92
93 public ArrayList Employees
94 {
95 get
96 {
97 return employees;
98 }
99 }
100 // Override the CreateChildControls method to
101 // add child controls to the Employees property when this
102 // custom control is requested from a page.
103 protected override void CreateChildControls()
104 {
105 Label label = new Label();
106 label.Text = Header;
107 label.BackColor = System.Drawing.Color.Beige;
108 label.ForeColor = System.Drawing.Color.Red;
109 Controls.Add(label);
110 Controls.Add(new LiteralControl("<BR> <BR>"));
111
112 Table table = new Table();
113 TableRow htr = new TableRow();
114
115 TableHeaderCell hcell1 = new TableHeaderCell();
116 hcell1.Text = "Name";
117 htr.Cells.Add(hcell1);
118
119 TableHeaderCell hcell2 = new TableHeaderCell();
120 hcell2.Text = "Title";
121 htr.Cells.Add(hcell2);
122
123 TableHeaderCell hcell3 = new TableHeaderCell();
124 hcell3.Text = "Alias";
125 htr.Cells.Add(hcell3);
126 table.Rows.Add(htr);
127
128 table.BorderWidth = 2;
129 table.BackColor = System.Drawing.Color.Beige;
130 table.ForeColor = System.Drawing.Color.Red;
131 foreach (Employee employee in Employees)
132 {
133 TableRow tr = new TableRow();
134
135 TableCell cell1 = new TableCell();
136 cell1.Text = employee.Name;
137 tr.Cells.Add(cell1);
138
139 TableCell cell2 = new TableCell();
140 cell2.Text = employee.Title;
141 tr.Cells.Add(cell2);
142
143 TableCell cell3 = new TableCell();
144 cell3.Text = employee.Alias;
145 tr.Cells.Add(cell3);
146
147 table.Rows.Add(tr);
148 }
149 Controls.Add(table);
150
151 }
152 }
153 }
3)TemplateContainerAttribute 类
声明在创建后将包含模板的 INamingContainer 的类型。
System.Object
System.Attribute
System.Web.UI.TemplateContainerAttribute
概要:将ITemplate属性的容器控件的类型通知解析器。解析器把这个类型作为数据绑定表达式中的Container的确切类型。
应用:类型为ITemplate的属性
样例中的使用:[TemplateContainer(typeof(FirstTemplateContainer))]
示例:
2
3 using System;
4 using System.Web;
5 using System.Web.UI;
6 using System.Web.UI.WebControls;
7 using System.Collections;
8
9 namespace CustomControls
10 {
11 [ParseChildren(true)]
12 public class TemplatedFirstControl : Control, INamingContainer
13 {
14 private ITemplate firstTemplate;
15 private String text = null;
16 private Control myTemplateContainer;
17
18 [System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name="FullTrust")]
19 protected override void OnDataBinding(EventArgs e)
20 {
21 EnsureChildControls();
22 base.OnDataBinding(e);
23 }
24
25
26 [TemplateContainer(typeof(FirstTemplateContainer))]
27 public ITemplate FirstTemplate
28 {
29 get
30 {
31 return firstTemplate;
32 }
33 set
34 {
35 firstTemplate = value;
36 }
37 }
38
39 public String Text
40 {
41 get
42 {
43 return text;
44 }
45 set
46 {
47 text = value;
48 }
49 }
50
51 public String DateTime
52 {
53 get
54 {
55 return System.DateTime.Now.ToLongTimeString();
56 }
57
58 }
59
60 public Control MyTemplateContainer
61 {
62 get
63 {
64 return myTemplateContainer;
65 }
66 }
67
68 [System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name="FullTrust")]
69 protected override void CreateChildControls ()
70 {
71 if (FirstTemplate != null)
72 {
73 myTemplateContainer = new FirstTemplateContainer(this);
74 FirstTemplate.InstantiateIn(myTemplateContainer);
75 Controls.Add(myTemplateContainer);
76 }
77 else
78 {
79 Controls.Add(new LiteralControl(Text + " " + DateTime));
80 }
81 }
82
83 }
84
85
86 public class FirstTemplateContainer : Control, INamingContainer
87 {
88 private TemplatedFirstControl parent;
89 public FirstTemplateContainer(TemplatedFirstControl parent)
90 {
91 this.parent = parent;
92 }
93
94 public String Text
95 {
96 get
97 {
98 return parent.Text;
99 }
100 }
101
102 public String DateTime
103 {
104 get
105 {
106 return parent.DateTime;
107 }
108
109 }
110 }
111 }