分享
 
 
 

ASP.NET编程入门随想之信客

王朝asp·作者佚名  2006-11-24
窄屏简体版  字體: |||超大  

记得早年在乡间,对外的通信往来主要依靠一种特殊职业的人:信客。外出谋生的人多了,少不了要带几封平安家信、捎一点衣物食品的,那就用得着信客了。信客要有一点文化,知道各大码头的情形,还要一副强健的筋骨,背得动重重的行李。信客沉重的脚步,是乡村和城市的纽带。

-- 余秋雨《文化苦旅·信客》

■ 一个馒头引发的血案 - 回发与事件

基于WEB的分布式系统中,用户往往是通过提交表单,浏览器产生相应的HTTP POST请求来完成交互过程,这个过程称为回发(PostBack)。在同一个网页中,常会有许多HTML标签可能引起回发,申请交于服务器处理。

控件对应着客户端的HTML标签,有着自己的状态和行为。用户操作引起每一次回发,会调用页面中一个或多个控件行为修改其状态,也就是说,杯中的粉圆(《随想十》中对控件的比喻)之间是有关联的,用户拨动其中一个,可能引起其它粉圆震动。拓展开来,当用户操作或系统内部引发状态改变时,类需要发送一个消息给关联类,让关联类做相应的状态调整。在.NET框架中,这个消息被称为事件(event),发接消息的类被称为事件源(event source),关联类被称为事件接收者(event sink)。回发的处理过程,实质上是事件源调用事件接收者的行为函数,称为回调(callback)。

我们不希望在编译时就确定回调的对象,否则这种强耦合关系就意味着每次使用时需要拎一串关联粉圆放到杯子中。相反,我们希望到运行时再来确定回调关系,在.NET框架中,这种方式被定义成委托(delegate),我们在《随想七》和《随想八》已经对其有了初步的认识。事件基于发布-订阅机制,每一个产生事件的类都有一个委托成员(发布机制),在系统初始化时,接收器或其它类需要将具体的事件处理程序绑定到委托成员(订阅机制),运行时,系统自动完成回调。

■ 口信 -用户操作引发的服务器端事件

"终于有妇女来给信客说悄悄话:'关照他,往后带东西几次并一次,不要鸡零狗碎的';'你给他说说,那些货色不能在上海存存?我一个女人家,来强盗来贼怎麽办'……信客沉稳地点点头。"

用户会对客户端浏览器中的页面元素做出各种操作,浏览器可以通过JavaSript之类的脚本语言来捕获这些操作并且做出相应回应,但对服务器而言,它却常常视而不见。要产生服务器端事件,就必须在设计期让事件源对应的表单元素引发带有鲜明特征的回发,从而让页面能够正确识别,并传递给控件以做相应回调,完成用户操作到事件的映射过程。

ASP.NET用接口IPostBackEventHandler做为信客的口信,带回远方的消息,它包含一个方法:RaisePostBackEvent。在回传后,页面会在控件树中寻找与引发回传HTML元素的UniqueID相匹配的控件,并调用该方法,下例为依赖于用户点击引发事件的自定义控件范例。

// MyControls.cs 自定义控件集

using System;

using System.ComponentModel;

using System.Web.UI;

using System.Web.UI.WebControls;

namespace essay

{

public class myButton:WebControl,IPostBackEventHandler

{

//定义控件属性Text

public virtual string Text

{

get

{

string s =(string)ViewState["Text"];

return (s==null)?string.Empty:s;

}

set {ViewState["Text"]=value;}

}

//生成控件对应的HTML代码

protected override void Render(HtmlTextWriter writer)

{

writer.Write("<INPUT TYPE=submit name=" + this.UniqueID + " Value='"+this.Text+"' />");

}

//定义Click事件委托

public event EventHandler Click;

//把客户端提交映射到自定义的Click事件

void IPostBackEventHandler.RaisePostBackEvent(string eventArgument)

{ OnClick(EventArgs.Empty); }

//实现回调

protected virtual void OnClick(EventArgs e)

{ if(Click!=null)Click(this,e); }

}

}

■ 行李 - 回发数据引发的服务器端事件

"一次,村里一户人家的姑娘要出嫁,姑娘的父亲在上海谋生,托老信客带来两匹红绸。"

除了依赖于用户操作引发事件外,我们时常还需要根据回发的用户数据,来修改相应控件的状态,从而引发事件。

回发的客户端表单数据会被集中整理到包含数据名/值集的一个System.Collections.Specialized.NameValueCollection实例中,页面会利用UniqueID在控件树中寻找匹配控件,如果匹配控件实现接口IpostBackDataHandler,则调用LoadPostData方法更新状态并返回更新标识,RaisePostDataChangedEvent方法检查标识从而引发事件。下例为依赖于状态变化引发事件的自定义控件范例。拓展一下,可以更加灵活地使用这个事件机制,例如当用户输入特定数据时,也可以在此引发特定事件。

using System;

using System.Web;

using System.Web.UI;

using System.Collections.Specialized;

namespace essay {

public class MyTextBox: Control, IPostBackDataHandler

{

//定义控件属性Text

public String Text

{

get {return (String) ViewState["Text"];}

set {ViewState["Text"] = value;}

}

//生成控件对应的HTML代码

protected override void Render(HtmlTextWriter output)

{

writer.Write("<INPUT TYPE=text name=" + this.UniqueID + " Value='"+this.Text+"' />");

}

//定义TextChanged事件委托

public event EventHandler TextChanged;

//更新控件的Text状态并返回更新标识

//参数NameValueCollection为回发数据集

public virtual bool LoadPostData(string postDataKey, NameValueCollection values)

{

String presentValue = Text;

String postedValue = values[postDataKey];

if (!presentValue.Equals(postedValue))

{

Text = postedValue;

return true;

}

return false;

}

//检查更新标识引发自定义事件TextChanged

public virtual void RaisePostDataChangedEvent()

{OnTextChanged(EventArgs.Empty);}

//实现回调

protected virtual void OnTextChanged(EventArgs e)

{if (TextChanged != null)TextChanged(this,e);}

}

}

■ 眼神 - 非回发事件与完整的控件执行生命周期

"只要信客一回村,他家里总是人头济济。多数都不是来收发信、物的,只是来看个热闹。农民的眼光里,有羡慕,有嫉妒;比较得多了,也有轻蔑,有嘲笑。这些眼神,是千年故土对城市的探询。"

以上两个事件皆与回发有直接关系,利用.NET的事件框架,我们可以在控件中的任何一个地方引发非回发事件。例如我们可以在页面中加入对用户透明的用户行为分析处理控件,窥视其它控件状态从而引发其特定的事件。

至此,我们已经深入了解与控件执行相关的各种要素细节,最后,通过图11-2,我们小结一下控件完整的执行生命周期。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有