| ASP.NET 2.0服务器控件之复合控件概述 |
|
| 来源:天极yesky 作者: 加入时间:2006-10-27 访问次数:8 [大 中 小] |
|
针对这种情况,如果只采取类撰写的实现方法,那么很容易造成错误,并且生成的复合控件性能受到很大影响。最好的解决方法是重写CreateChildControls方法,同时也重写Render方法。在CreateChildControls方法中,为复合控件添加子控件;在Render方法中,为HTTP输出流添加用于格式化和布局的HTML。
下面列举了呈现复合控件的关键步骤:
· 控件基类继承自CompositeControl基类。这是在ASP.NET 2.0中创建复合控件的关键所在。
· 重写CreateChildControls方法,完成实例化、初始化子控件,并且将子控件添加到控件集合中。
· 重写ICompositeControlDesignerAccessor接口的RecreateChildContrls方法。
· 如果复合控件中存在用于格式化和布局的HTML,那么建议将这些内容写入Render方法中,而不要在CreateChildControls方法中创建和添加所需的LiteralControl实例。另外,在添加相关HTML代码过程中,为了让子控件使用默认生成方法,必须使每个子控件调用RenderControl方法。
为了便于读者更好的理解以上内容,下面举例说明。在此示例中,Register控件使用子控件创建用户界面(UI),用于输入用户信息,以向网站注册。此用户界面包括两个TextBox控件(一个用于输入用户名,另一个用于输入用户的电子邮件地址)和一个用于提交信息的Button控件。Register还将RequiredFieldValidator控件与两个TextBox控件关联起来,以确保用户输入了名称和电子邮件地址。复合控件Register源代码如下所示:
using System; using System.ComponentModel; using System.Drawing; using System.Security.Permissions; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; namespace WebControlLibrary{ [ DefaultProperty("ButtonText"), ToolboxData("<{0}:Register runat="server"> </{0}:Register>"), ]
public class Register : CompositeControl { // 定义私有字段 private Button submitButton; private TextBox nameTextBox; private Label nameLabel; private TextBox emailTextBox; private Label emailLabel; private RequiredFieldValidator emailValidator; private RequiredFieldValidator nameValidator; // 实现属性ButtonText
[ Bindable(true), Category("Appearance"), DefaultValue(""), Description("按钮上的文字内容.") ]
public string ButtonText { get { EnsureChildControls(); return submitButton.Text; } set { EnsureChildControls(); submitButton.Text = value; } }
// 实现属性Name
[ Bindable(true), Category("Default"), DefaultValue(""), Description("用户名.") ]
public string Name { get { EnsureChildControls(); return nameTextBox.Text; } set { EnsureChildControls(); nameTextBox.Text = value; } }
// 实现属性NameErrorMessage
[ Bindable(true), Category("Appearance"), DefaultValue(""), Description("用户名验证错误信息.") ]
public string NameErrorMessage { get { EnsureChildControls(); return nameValidator.ErrorMessage; } set { EnsureChildControls(); nameValidator.ErrorMessage = value; nameValidator.ToolTip = value; } }
// 实现属性NameLabelText
[ Bindable(true), Category("Appearance"), DefaultValue(""), Description("用户名文本框旁的文字.") ]
public string NameLabelText { get { EnsureChildControls(); return nameLabel.Text; } set { EnsureChildControls(); nameLabel.Text = value; } }
// 实现属性Email
[ Bindable(true), Category("Default"), DefaultValue(""), Description("邮件地址.") ]
public string Email { get { EnsureChildControls(); return emailTextBox.Text; } set { EnsureChildControls(); emailTextBox.Text = value; } }
// 实现属性EmailErrorMessage
[ Bindable(true), Category("Appearance"), DefaultValue(""), Description("邮件地址验证错误信息.") ]
public string EmailErrorMessage { get { EnsureChildControls(); return emailValidator.ErrorMessage; } set { EnsureChildControls(); emailValidator.ErrorMessage = value; emailValidator.ToolTip = value; } }
// 实现属性EmailLabelText
[ Bindable(true), Category("Appearance"), DefaultValue(""), Description("电子邮件文本框旁的文字.") ]
public string EmailLabelText { get { EnsureChildControls(); return emailLabel.Text; } set { EnsureChildControls(); emailLabel.Text = value; } }
// 重写ICompositeControlDesignerAccessor接口的RecreateChildContrls方法
protected override void RecreateChildControls() { EnsureChildControls(); }
// 重写Control基类的CreateChildControls方法
protected override void CreateChildControls() { // 清除所有子控件 Controls.Clear(); nameLabel = new Label(); nameTextBox = new TextBox(); nameTextBox.ID = "nameTextBox"; nameValidator = new RequiredFieldValidator(); nameValidator.ID = "validator1"; nameValidator.ControlToValidate = nameTextBox.ID; nameValidator.Text = NameErrorMessage; nameValidator.Display = ValidatorDisplay.Static; emailLabel = new Label(); emailTextBox = new TextBox(); emailTextBox.ID = "emailTextBox"; emailValidator = new RequiredFieldValidator(); emailValidator.ID = "validator2"; emailValidator.ControlToValidate = emailTextBox.ID; emailValidator.Text = EmailErrorMessage; emailValidator.Display = ValidatorDisplay.Static; submitButton = new Button(); submitButton.ID = "button1"; this.Controls.Add(nameLabel); this.Controls.Add(nameTextBox); this.Controls.Add(nameValidator); this.Controls.Add(emailLabel); this.Controls.Add(emailTextBox); this.Controls.Add(emailValidator); this.Controls.Add(submitButton); }
// 重写Render方法
protected override void Render(HtmlTextWriter writer) { AddAttributesToRender(writer); writer.AddAttribute(HtmlTextWriterAttribute.Cellpadding, "1", false); writer.RenderBeginTag(HtmlTextWriterTag.Table); writer.RenderBeginTag(HtmlTextWriterTag.Tr); writer.RenderBeginTag(HtmlTextWriterTag.Td); nameLabel.RenderControl(writer); writer.RenderEndTag(); writer.RenderBeginTag(HtmlTextWriterTag.Td); nameTextBox.RenderControl(writer); writer.RenderEndTag(); writer.RenderBeginTag(HtmlTextWriterTag.Td); nameValidator.RenderControl(writer); writer.RenderEndTag(); writer.RenderEndTag(); writer.RenderBeginTag(HtmlTextWriterTag.Tr); writer.RenderBeginTag(HtmlTextWriterTag.Td); emailLabel.RenderControl(writer); writer.RenderEndTag(); writer.RenderBeginTag(HtmlTextWriterTag.Td); emailTextBox.RenderControl(writer); writer.RenderEndTag(); writer.RenderBeginTag(HtmlTextWriterTag.Td); emailValidator.RenderControl(writer); writer.RenderEndTag(); writer.RenderEndTag(); writer.RenderBeginTag(HtmlTextWriterTag.Tr); writer.AddAttribute(HtmlTextWriterAttribute.Colspan, "2", false); writer.AddAttribute(HtmlTextWriterAttribute.Align, "right", false); writer.RenderBeginTag(HtmlTextWriterTag.Td); submitButton.RenderControl(writer); writer.RenderEndTag(); writer.RenderBeginTag(HtmlTextWriterTag.Td); writer.Write(" "); writer.RenderEndTag(); writer.RenderEndTag(); writer.RenderEndTag(); } } } | 以上列举了复合控件类Register的源代码。虽然代码有些冗长,然而还是比较容易理解的。下图1列举了Register类结构图。
|
|
|
|
|
|