2. 实现方法
上一小节中的Default.ASPx页面所包含的Company控件具有3个连字符形式复杂属性。它们是如何实现的呢?实际上,实现这种形式的复杂属性关键是,在自定义服务器控件实现过程中,对复杂属性及其子属性设置特定的设计时元数据。
对于复杂属性而言,主要在该属性实现前设置两个设计时元数据:DesignerSerializationVisibility和NotifyParentProperty。DesignerSerializationVisibility用于指定在设计时序列化组件上的属性时,所使用的持久性类型。NotifyParentProperty可使得属性浏览器中对子属性的修改通知一直上传到对象模型,并在被修改了子属性的控件中产生修改通知。对于子属性的设计时元数据设置比较简单,只需在子属性实现前设置一个NotifyParentProperty即可。
实现自定义服务器控件Company涉及两个文件:Company.cs和Employee.cs。前者是自定义服务器控件的实现主体,其中包括各种属性设置、控件呈现方法RenderContents等等。后者用于实现复杂属性Employee。下面首先列举了Company.cs文件源代码。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace WebControlLibrary{
[DefaultProperty("Text")]
[ToolboxData("<{0}:Company runat=server></{0}:Company>")]
public class Company : WebControl {
private Employee employee; //实现属性City
[ Bindable(true), Category("Appearance"), DefaultValue(""), Description("公司所在城市") ]
public string City {
get {
string _city = (String)ViewState["City"];
return ((_city == null)?String.Empty:_city);
}
set { ViewState["City"] = value; }
} //实现属性Employee
[ Bindable(true), Category("Appearance"), Description("员工信息"), DesignerSerializationVisibility( DesignerSerializationVisibility.Content), NotifyParentProperty(true) ]
public Employee Employee {
get {
if (employee == null) {
employee = new Employee();
}
return employee;
}
} // 重写RenderContents方法,自定义实现控件呈现
protected override void RenderContents(HtmlTextWriter output) {
output.Write("公司所在城市:");
output.Write(City);
output.WriteBreak();
output.Write("姓名:");
output.Write(Employee.Name.ToString());
output.WriteBreak();
output.Write("性别:");
output.Write(Employee.Sex.ToString());
output.WriteBreak();
output.Write("职务:");
output.Write(Employee.Title.ToString());
}
}
}
以上代码显示了自定义服务器控件Company的实现,其中主要包括了一些属性和RenderContents方法的内容。具体属性包括2个:一个是简单属性City,另一个是复杂属性Employee。简单属性City的实现使用了视图状态ViewState。复杂属性Employee则有些特别,其类型是一个类Employee。同时,该属性还设置了两个元数据属性:DesignerSerializationVisibility(DesignerSerializationVisibility.Content)和NotifyParentProperty(true)。前者可用于指定序列化程序应该序列化属性的内容即子属性,后者则可使得属性浏览器中对子属性的修改通知一直上传到对象模型,并在被修改了子属性的控件中产生修改通知。以上两个设计时元数据属性的设置是实现连字符形式复杂属性的关键之一。另一个关键之处在于为在实现复杂属性的子属性时未其设置元数据属性。
做人要厚道,请注明转自酷网动力(www.ASPCOOL.COM)。