18.8 组合式控件
组合式控件,也称为复合控件,它使用现有的子控件来创建用户界面和执行其他逻辑。由于组合式控件的功能依赖于子控件,因此,与自己实现所有控件功能相比,开发组合式控件要简单轻松得多。
要创建组合式控件,必须从System.Web.UI.WebControls.CompositeControl类(它自身也是从WebControl类派生的)派生出一个新的控件类。然后,必须覆盖它的CreateChildControls方法来添加子控件。这时,可以创建一个或者多个控件对象,设置它们的属性和事件处理程序,最后把它们加入到当前控件的Controls集合中。
下面的MyLogin控件演示了一个简单的登录控件的创建,如代码清单18-7所示。
代码清单18-7 MyLogin.cs
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_18_1
{
[AspNetHostingPermission(SecurityAction.Demand,
Level=AspNetHostingPermissionLevel.Minimal),
AspNetHostingPermission(SecurityAction.InheritanceDemand,
Level=AspNetHostingPermissionLevel.Minimal),
DefaultEvent("Login"),
DefaultProperty("ButtonText"),
ToolboxData("<{0}:MyLogin runat=\"server\"></{0}:MyLogin>")]
public class MyLogin:CompositeControl
{
private Button loginButton;
private TextBox nameTextBox;
private Label nameLabel;
private TextBox passwordTextBox;
private Label passwordLabel;
private static readonly object EventLoginKey=
new object();
[Bindable(true),
Category("Appearance"),
DefaultValue(""),
Description("The text to display on the button.")]
public string ButtonText
{
get
{
EnsureChildControls();
return loginButton.Text;
}
set
{
EnsureChildControls();
loginButton.Text=value;
}
}
[Bindable(true),
Category("Default"),
DefaultValue(""),
Description("The user name.")]
public string Name
{
get
{
EnsureChildControls();
return nameTextBox.Text;
}
set
{
EnsureChildControls();
nameTextBox.Text=value;
}
}
[Bindable(true),
Category("Appearance"),
DefaultValue(""),
Description("The text for the name label.")]
public string NameLabelText
{
get
{
EnsureChildControls();
return nameLabel.Text;
}
set
{
EnsureChildControls();
nameLabel.Text=value;
}
}
[Bindable(true),
Category("Default"),
DefaultValue(""),
Description("The passWord.")]
public string PassWord
{
get
{
EnsureChildControls();
return passwordTextBox.Text;
}
set
{
EnsureChildControls();
passwordTextBox.Text=value;
}
}
[Bindable(true),
Category("Appearance"),
DefaultValue(""),
Description("The text for the passWord label.")]
public string PassWordLabelText
{
get
{
EnsureChildControls();
return passwordLabel.Text;
}
set
{
EnsureChildControls();
passwordLabel.Text=value;
}
}
[Category("Action"),
Description("Raised when the user clicks the button.")]
public event EventHandler Login
{
add
{
Events.AddHandler(EventLoginKey, value);
}
remove
{
Events.RemoveHandler(EventLoginKey, value);
}
}
protected virtual void OnLogin(EventArgs e)
{
EventHandler SubmitHandler=
((EentHandler)Events[EventLoginKey];
if(SubmitHandler!=null)
{
SubmitHandler(this, e);
}
}
private void_button_Click(object source, EventArgs e)
{
OnLogin(EventArgs.Empty);
}
protected override void RecreateChildControls()
{
EnsureChildControls();
}
protected override void CreateChildControls()
{
Controls.Clear();
nameLabel=new Label();
nameTextBox=new TextBox();
nameTextBox.ID="nameTextBox";
passwordLabel=new Label();
passwordTextBox=new TextBox();
passwordTextBox.ID="passwordTextBox";
passwordTextBox.TextMode=TextBoxMode.Password;
loginButton=new Button();
loginButton.ID="button1";
loginButton.Click
+=new EventHandler(_button_Click);
this.Controls.Add(nameLabel);
this.Controls.Add(nameTextBox);
this.Controls.Add(passwordLabel);
this.Controls.Add(passwordTextBox);
this.Controls.Add(loginButton);
}
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.RenderEndTag();
writer.RenderBeginTag(HtmlTextWriterTag.Tr);
writer.RenderBeginTag(HtmlTextWriterTag.Td);
passwordLabel.RenderControl(writer);
writer.RenderEndTag();
writer.RenderBeginTag(HtmlTextWriterTag.Td);
passwordTextBox.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);
loginButton.RenderControl(writer);
writer.RenderEndTag();
writer.RenderBeginTag(HtmlTextWriterTag.Td);
writer.Write(" ");
writer.RenderEndTag();
writer.RenderEndTag();
writer.RenderEndTag();
}
}
}
创建好MyLogin控件之后,可以在页面上使用该控件。如下面的代码所示:
<form id="form1"runat="server">
<div>
<cc1:MyLogin ID="MyLogin1"runat="server"ButtonText="登录"
NameLabelText="用户名称:"
PasswordLabelText="登录密码:"
onlogin="MyLogin1_Login"/>
<br/>
<asp:Label ID="Label1"Runat="server"Text="Label">
</asp:Label>
</div>
</form>
MyLogin1_Login事件处理程序代码如下所示:
protected void Page_Load(object sender, EventArgs e)
{
Label1.Visible=false;
}
protected void MyLogin1_Login(object sender, EventArgs e)
{
if(this.MyLogin1.Name=="mawei"
&&this.MyLogin1.PassWord=="password")
{
Label1.Text=String.Format(
"欢迎你,{0}!你已经登录成功.",this.MyLogin1.Name);
Label1.Visible=true;
MyLogin1.Visible=false;
}
else
{
Label1.Text="你的用户名称与密码错误!";
Label1.Visible=true;
}
}
示例运行结果如图18-10所示。
图 18-10 MyLogin控件的示例运行结果