在前面的系列文章中,笔者已经列举了几个实现自定义服务器控件的示例。通过这些示例,读者初步接触了有关创建服务器控件属性的内容。例如,使用私有变量、视图状态、控件状态等实现属性等等。虽然读者通过这些内容可以了解实现属性的一些基本知识,但是这还是不够的。从本节开始,将针对实现自定义服务器控件属性的问题展开讲解。本节重点介绍实现自定义服务器控件属性的一些基本概念和简单属性的基本实现方法等内容。
1. 控件属性基本概念 <MyControl:CustomerControl id="demo1" runat="server" PropertyName="PropertyValue"/>
其中PropertyName为一个不带连字符的单词。例如: <asp:Button id="button1" runat="server" Text="Submit"/>
此处的属性Text属于通用形式属性。 · 连字符形式属性 这种标记形式的属性位于控件标记内部,带有连字符是这种形式属性的最大特征。其形式为: <MyControl:CustomerControl id="demo1" runat="server" Sub-PropertyName="PropertyValue"/>
其中Sub-PropertyName为一个带连字符的单词组合。例如: <asp:Label id="label1" runat="server" Font-Size="Medium" Font-Underline="True" />
在上面的代码中,Font-Size和Font-Underline就是典型的连字符形式属性。 · 内部嵌套形式属性 凡是具有这种标记形式的属性均为复杂属性。它是以嵌套形式在控件标记内部声明某属性集的子属性。其形式类似: <asp:DataGrid id="DataGrid1" runat="server">
<HeaderStyle ForeColor="#FFFFCC" BackColor="#990000"> </HeaderStyle> <FooterStyle ForeColor="#330099" BackColor="#FFFFCC"> </FooterStyle> </asp:DataGrid> 其中HeaderStyle是内部嵌套形式属性,ForeColor和BackColor是HeaderStyle属性的子属性。FooterStyle与HeaderStyle是一样的,也是内部嵌套形式属性。 · 内部嵌套形式默认属性 这种标记形式的属性通常用于服务器控件的集合属性,具有这种形式的属性必然是复杂属性。该形式属性与上文所述"内部嵌套形式属性"的标记形式基本相同。不同之处在于:当某控件具有这种属性时,控件标记中只包含该形式属性,不能包含其他任何属性。这就是为什么称为"默认"的原因。其形式类似: <asp:DropDownList id="DropDownList1" runat="server">
<asp:ListItem>1</asp:ListItem> <asp:ListItem>2</asp:ListItem> <asp:ListItem>3</asp:ListItem> <asp:ListItem>4</asp:ListItem> </asp:DropDownList>
2) 从Control和WebControl继承的属性
页框架 如前面文章所述,如果创建具有UI的自定义服务器控件,则应该从WebControl或System.Web.UI.WebControls中的任何控件派生,该命名空间为自定义控件提供适当的起点。同样的道理,读者应了解一些来自WebControl类的常见属性,它们可为控件自动继承。表2列举了这些属性。
3) 与属性相关的设计时元数据 创建服务器控件是为了提高应用开发效率,每个控件开发者都希望自己创建出的控件能够像.NET框架中的内置标准服务器控件那样功能强大且易于使用。例如,当控件应用者在设计界面点击控件时,可能会希望某些属性能够高亮显示,某些属性能够显示在属性浏览器中等等。如何才能使控件具有这样的功能呢?这就需要在代码中加入相关的设计时支持代码。 实际上,实现设计时元数据是一个比较复杂的内容。然而,作为初学者而言,我们没有必要掌握得过于深入,下面笔者只讲解一些常见的与属性相关的设计时元数据设置。如下所示代码,列举了一些与属性相关的设计时元数据设置和简要说明。 · Bindable 这个特性表示属性是否可以绑定一个有效数据源。通常使用布尔值进行设置,例如:Bindable(true)。如果使用值true标记属性,表示该属性可以绑定一个有效数据源,且应引发该属性的属性更改通知;如果属性值为false,则表示该属性不能绑定数据。 · Browsable 指定属性是否应该在属性浏览器中显示,使用布尔值设置。通常情况下,公用属性和那些希望在属性浏览器中显示的属性被设置为Browsable(true),只读属性和那些不希望在属性浏览器中见到的属性被设置为Browsable(false)。 · Category 指定属性在属性浏览器中进行分组显示的类别。该设计时特性帮助可视化编辑器将属性进行逻辑分组。通常分为:外观(Appearance)、行为(Behavior)、布局(Layout)、数据(Data)、操作(Action)、键盘(Key)、鼠标(Mouse)等。除此之外,读者还可以自定义分类,例如Category("ItemStyle"),表示该属性在属性浏览器中显示为ItemStyle一组。 · Description 指定显示在属性浏览器下方,属性的文字说明。例如:Description("this is a property")。 以上内容是实现属性过程中最为常见的设计时元数据设置。无论对于简单属性,还是复杂属性都应该根据需要设置。 · DesignerSerializationVisibility 指定属性是否以及如何在代码中序列化,其值为DesignerSerializationVisibility的枚举值。存在三种设置方式: (1)DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),指定序列化程序不应该序列化属性的值; (2)DesignerSerializationVisibility(DesignerSerializationVisibility.Visible),指定应该允许序列化程序序列化属性的值; (3)DesignerSerializationVisibility(DesignerSerializationVisibility.Content),指定序列化程序应该序列化属性的内容,而不是属性本身。此字段为只读。需要注意的是:没有DesignerSerializationVisibility特性的成员将被视为具有值为DesignerSerializationVisibility.Visible的DesignerSerializationVisibility特性。如果可能,序列化程序会将标记为Visible的属性值序列化为该类型。 · NotifyParentProperty 指示当此特性应用到的属性的值被修改时将通知其父属性。换言之,如果属性的父属性应该在该属性值更改时接到通知,则向该属性应用NotifyParentProperty特性。通常使用布尔值进行设置。例如,Size属性具有两个嵌套的子属性:Width和Height。那么属性Width和Height就应标记为NotifyParentPropertyAttribute(true),以便当属性值更改时,它们可以通知父属性来更新其值并显示。 · ParseChildren 使用该特性指示当在页上以声明方式使用控件时,嵌套在服务器控件标记内的XML元素是应该视为属性还是应视为子控件。通常情况下,包含两种声明方式:(1)ParseChildren(true),表示将子XML元素作为服务器控件的属性分析,ParseChildren(false),表示将子XML元素作为服务器控件的子控件分析;(2)ParseChildren(bool childrenasProperty , string defaultProperty),其中childrenasPropety和方式1中的布尔值参数意义相同,defaultProperty定义默认情况下将子控件分析为的服务器控件的集合属性。 · PersistChildren 该特性指示设计时是否应将服务器控件的子控件作为内部嵌套控件保持。如果该特性为PersistChildren(true),则将服务器控件的子控件作为嵌套服务器控件标记保持。如果为PersistChildren(false),则将该控件的属性作为嵌套元素保持。 · PersistenceMode 指定如何将服务器控件属性或事件保持到ASP.NET页的元数据属性。共存在4种枚举设置方式: (1)PersistenceMode(PersistenceMode.Attribute),指定属性或事件保持为特性; (2)PersistenceMode(PersistenceMode.EncodedInnerDefaultProperty),指定属性作为服务器控件的唯一内部文本而。属性值是HTML编码的。只能对字符串做这种指定; (3)PersistenceMode(PersistenceMode.InnerDefaultProperty),指定属性在服务器控件中保持为内部文本。还指示将该属性定义为元素的默认属性。只能指定一个属性为默认属性; (4)PersistenceMode(PersistenceMode.InnerProperty),指定属性在服务器控件中保持为嵌套标记。这通常用于复杂对象;它们具有自己的持久性属性; · DefaultProperty 指定服务器控件的默认属性。例如:[DefaultProperty("MyProperty")]。 · TypeConverter 指定用作此特性所绑定到的对象的转换器的类型。用于转换的类必须从TypeConverter继承。使用ConverterTypeName属性来获取为该特性所绑定到的对象提供数据转换的类名。 2. 简单属性实现方法 // 定义枚举
public enum BookType{ NotDefined = 0, Fiction = 1, NonFiction = 2 } // 实现属性BookType[Bindable(true),Category("Appearance"),DefaultValue(BookType.NotDefined),Description("Fiction or Not"),] public virtual BookType BookType{ get { object t = ViewState["BookType"]; return (t == null) ? BookType.NotDefined : (BookType)t; } set { ViewState["BookType"] = value; } } 以上代码实现了一个枚举BookType(包括3个枚举值)和一个类型为BookType的属性BookType。根据前文所述基本概念可知,BookType是一个简单属性。同时,该属性将属性值存储在视图状态ViewState中。通过这个实例,我们基本可以总结出简单属性的实现方法: (1)判断所要声明的属性是否是通用形式属性; (2)判断所要声明的属性所封装的属性值是否是简单数值类型、String还是枚举类型等; (3)如果步骤1和2都为真,则判定所要声明的属性是简单属性; (4)声明该属性的设计时特性; (5)根据属性的设计需求,编写读写访问器代码; 3. 小结 本文介绍了利用ASP.NET 2.0技术,为自定义服务器控件创建简单属性的内容。随着读者对自定义服务器控件开发的逐步理解将会发现,实现简单属性是构建控件过程中较为简单,也是较为常见的实现内容。在创建过程中,读者必须了解使用私有变量、控件状态和视图状态的不同之处。这样才能又快又好的实现简单属性。 |
![](https://img2024.cnblogs.com/blog/35695/202407/35695-20240713070336838-1837943664.jpg)