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所示。

figure_0679_0506

图 18-10 MyLogin控件的示例运行结果