** 在asp.net中为Web用户控件添加属性和事件 **
在90年代初,Microsoft为Web程序员提供的 Active Server Pages(ASP)革命性地改变了Web的编程。它可以利用十分易用的模型在Web服务器上动态生成HTML,并且很容易的实现了对数据库的访问,就当时来说,这是一项多么吸引人的技术,包括现在Internet上的许多web站点都是用Asp写的,我的同事前辈们更是玩Asp的高手,经历这么多年而不衰,可见他的成功。
但是,技术是在不断的发展着,引用某位Net专家的话讲――如今Web编程的状态还是落后的。因此Microsoft提出了第二代编程模型――Web窗体。Web窗体模型作为Asp.net的一部分,而Asp.net又是.Net框架的一个部分。他的编程模型是基于事件的,使用他更像是在进行Windows窗体编程,这一点也正是我决定去学习使用他的一个重要原因,也胡乱看了一些这方面的书,写这篇文章的目的也就是和各位Asp.net初学者和还没有为用户控件添加过自定义事件的同行分享一下经验。
废话少说,下面就让我们先建立一个用户控件吧,这里就用一个简单登录用户控件来做演示。
先来看看用户控件的前台代码(LogInOutControl.ascx文件):
1@ Control Language="c#" AutoEventWireup="false" Codebehind="LogInOutControl.ascx.cs" Inherits="ZZ.LogInOutControl" TargetSchema=" _http://schemas.microsoft.com/intellisense/ie5"%_ >
<table align="center" border="1" cellpadding="1" cellspacing="1" id="Table1" style="FONT-SIZE: 9pt; WIDTH: 183px; HEIGHT: 125px" width="183"> <tr> <td height="20"> <asp:label id="LabelUser" runat="server">用户:</asp:label> <asp:textbox id="TextBoxUserName" runat="server" width="128px"></asp:textbox></td> </tr> <tr> <td height="20"><font face="宋体"> <asp:label id="LabelPassword" runat="server">密码:</asp:label> <asp:textbox id="TextBoxPassword" runat="server" textmode="Password" width="128px"></asp:textbox></font></td> </tr> <tr> <td align="center" height="20"><font face="宋体"> <asp:button id="ButtonLogIn" runat="server" text="登录" width="50px"></asp:button> <asp:button id="ButtonLogOut" runat="server" text="注销" width="49px"></asp:button></font></td> </tr> </table>
1---
2
3我们简单的放了两个Label,两个TextBox,两个Button以及一个Html表。
4接下去就是为LogInOutControl.ascx.cs文件添加代码了。
5首先定义一个delegate,其中LogInOutEventArgs类是从EventArgs类继承,
6public delegate void LogInOutClickHandler(object sender,LogInOutEventArgs e);
7---
8
9我觉得把这个delegate放在LogInOutControl类外面更为合适。
10接下去为控件声明了LogInOutClick事件,如下:
11public event LogInOutClickHandler LogInOutClick;
12---
13
14另外为了更好的使用属性,加了Language枚举,
15private Language language;
16---
17
18当然外部通过public Language Lg {get;set;}属性来访问。目的就是改变或者获取当前控件的显示。
19接下去就是定义控件事件触发函数OnLogInOutClick,由按钮单击事件处理函数来完成对用户控件事件的触发。
20完整代码如下:
21namespace ZZ
22{
23using System;
24using System.Data;
25using System.Drawing;
26using System.Web;
27using System.Web.UI.WebControls;
28using System.Web.UI.HtmlControls;
29
30// 定义代理
31public delegate void LogInOutClickHandler(object sender,LogInOutEventArgs e);
32public class LogInOutControl : System.Web.UI.UserControl
33{
34protected System.Web.UI.WebControls.Button ButtonLogIn;
35protected System.Web.UI.WebControls.TextBox TextBoxUserName;
36protected System.Web.UI.WebControls.TextBox TextBoxPassword;
37protected System.Web.UI.WebControls.Button ButtonLogOut;
38protected System.Web.UI.WebControls.Label LabelUser;
39protected System.Web.UI.WebControls.Label LabelPassword;
40public event LogInOutClickHandler LogInOutClick;
41private Language language;
42//方法
43public void ChangeLanguage(Language language)
44{
45this.Lg = language;
46}
47//属性
48public Language Lg
49{
50set
51{
52if(value!=this.language)
53{
54if(value==Language.English)
55{
56this.LabelUser.Text = "User:";
57this.LabelPassword.Text ="Password:";
58this.ButtonLogIn.Text = "LogIn";
59this.ButtonLogOut.Text = "LogOut";
60}
61else
62{
63this.LabelUser.Text = "用户:";
64this.LabelPassword.Text ="密码:";
65this.ButtonLogIn.Text = "登录";
66this.ButtonLogOut.Text = "注销";
67}
68}
69}
70}
71private void Page_Load(object sender, System.EventArgs e)
72{
73if(this.LabelUser.Text=="User:")
74this.language = Language.English;
75else
76this.language = Language.Chinese;
77}
78private void OnLogInOutClick(object sender,LogInOutEventArgs e)
79{
80if(LogInOutClick!=null)
81LogInOutClick(this,e);
82}
83#region Web 窗体设计器生成的代码
84override protected void OnInit(EventArgs e)
85{
86InitializeComponent();
87base.OnInit(e);
88}
89private void InitializeComponent()
90{
91this.ButtonLogIn.Click += new System.EventHandler(this.ButtonLogIn_Click);
92this.ButtonLogOut.Click += new System.EventHandler(this.ButtonLogOut_Click);
93this.Load += new System.EventHandler(this.Page_Load);
94}
95#endregion
96private void ButtonLogIn_Click(object sender, System.EventArgs e)
97{
98OnLogInOutClick(this,new LogInOutEventArgs(LogInClickType.LongIn,CustomValidate(this.TextBoxUserName.Text,this.TextBoxPassword.Text)));
99}
100private void ButtonLogOut_Click(object sender, System.EventArgs e)
101{
102//注销代码省略
103OnLogInOutClick(this,new LogInOutEventArgs(LogInClickType.LongOut,true));
104}
105//验证函数
106private bool CustomValidate(string userName,string password)
107{
108//验证代码省略,假设通过
109return true;
110}
111}
112}
113
114
115---
116
117
118另外一个文件定义了枚举和参数类:
119using System;
120namespace ZZ
121{
122public class LogInOutEventArgs : EventArgs
123{
124private LogInClickType type;
125private bool result;
126
127public LogInOutEventArgs(LogInClickType type,bool result):base()
128{
129this.type = type;
130this.result = result;
131}
132public LogInClickType Type
133{
134get{return this.type;}
135}
136//操作结果,
137public bool Result
138{
139get{return this.result;}
140}
141}
142//操作类型
143public enum LogInClickType : int
144{
145LongIn,
146LongOut
147}
148//定义语言
149public enum Language
150{
151Chinese,
152English
153}
154}
155
156---
157
158接下去看看在aspx页面里面使用。
159新建一个Default.aspx页面,拖一个LogInOutControl用户控件到上面。
160<%@ Register TagPrefix="uc1" TagName="LogInOutControl" Src="LogInOutControl.ascx"
1@ Page language="c#" Codebehind="Default.aspx.cs" AutoEventWireup="false" Inherits="ZZ.Default"
1@ Import Namespace="ZZ"
1<html>
2<head>
3<title>WebForm1</title>
4</head>
5<body>
6<form id="Form1" method="post" runat="server">
7<font face="宋体">
8<uc1:loginoutcontrol id="LogInOutControl1" runat="server">
9</uc1:loginoutcontrol>
10<asp:label id="LabelMsg" runat="server"></asp:label>
11<asp:dropdownlist autopostback="True" id="DropDownList1" runat="server">
12<asp:listitem selected="True" value="0">中文</asp:listitem>
13<asp:listitem value="1">英文</asp:listitem>
14</asp:dropdownlist></font>
15</form>
16</body>
17</html>
在后台代码中添加事件和属性。
虽然在前台添加了LogInOutControl1,但是后台代码中不会生成protected LogInOutControl LogInOutControl1;这条语句,我觉得很奇怪,不管先加上他。
接着在Page_Load事件中注册LogInOutClick事件:
this.LogInOutControl1.LogInOutClick += new LogInOutClickHandler(LogInOutControl1_LogInOutClick);
完整代码如下:
using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
namespace ZZ
{
public class Default : System.Web.UI.Page
{
protected System.Web.UI.WebControls.Label LabelMsg;
protected System.Web.UI.WebControls.DropDownList DropDownList1;
protected LogInOutControl LogInOutControl1;
private void Page_Load(object sender, System.EventArgs e)
{
//注册用户控件事件
this.LogInOutControl1.LogInOutClick += new LogInOutClickHandler(LogInOutControl1_LogInOutClick);
}
#region Web 窗体设计器生成的代码
override protected void OnInit(EventArgs e)
{
InitializeComponent();
base.OnInit(e);
}
private void InitializeComponent()
{
this.DropDownList1.SelectedIndexChanged += new System.EventHandler(this.DropDownList1_SelectedIndexChanged);
this.Load += new System.EventHandler(this.Page_Load);
}
#endregion
private void LogInOutControl1_LogInOutClick(object sender, LogInOutEventArgs e)
{
switch(e.Type)
{
case LogInClickType.LongIn:
this.LabelMsg.Text = "你点击了登录按钮,操作结果:"+e.Result.ToString();
break;
case LogInClickType.LongOut:
this.LabelMsg.Text = "你点击了注销按钮,操作结果:"+e.Result.ToString();
break;
}
}
private void DropDownList1_SelectedIndexChanged(object sender, System.EventArgs e)
{
this.LogInOutControl1.Lg = (Language)this.DropDownList1.SelectedIndex;
//this.LogInOutControl1.ChangeLanguage((Language)this.DropDownList1.SelectedIndex);
}
}
}
当用户在前台通过选择下拉框列表来改变控件的语言,这里通过Lg属性来完成,不过这里也加了一个方法ChangeLanguage也可以实现同样的功能。另外,通过点击登陆或注销按钮触发LogInOutClick事件来给页面中的LabelMsg.Text属性赋值从而得到操作结果。
总结,用户控件为程序员带来了很高的开发效率和重用性,更是在性能方面有了很大的提高,以前称为Asp+,其实我认为Asp.net跟Asp没有什么直接联系。而且我想做应用程序的朋友和我一样在开发Web程序时更喜欢采用代码分离方式,这样结构更清晰,便与修改和管理。同Asp程序相比,他是编译型的,引入了面向对象的设计思想,也就不可避免的带来了他的复杂性,要想开发高水准的Asp.net程序,对于模式的设计,层次结构的划分,这里还是比较讲究的。总之,他更像是在编Windows窗体程序,而不是在写VB脚本。