网站导航网学 原创论文 原创专题 网站设计 最新系统 原创论文 论文降重 发表论文 论文发表 UI设计定制 论文答辩PPT格式排版 期刊发表 论文专题
返回网学首页
网学原创论文
最新论文 推荐专题 热门论文 论文专题
当前位置: 网学 > 设计资源 > .Net编程 > 正文

ASP.NET页面生命周期的整体把握

论文降重修改服务、格式排版等 获取论文 论文降重及排版 论文发表 相关服务

先看下下面4个相关页面的代码(为降低复杂度,很多代码被删减与精简,仅提供最基本的操作代码)。仅仅几个文件,先看下整体文件的布局,有一个整体的把握。              

(一)父类的相关事件以及处理

  1. public class UserParentPage:System.Web.UI.Page 
  2.   { 
  3.       /// <summary> 
  4.       /// 对回传数据的处理,以及其他内容的设置、获取 
  5.       /// </summary> 
  6.       /// <param name="e"></param> 
  7.       protected override void OnInit(EventArgs e) 
  8.       { 
  9.           Core.Trace.TraceInfo("UserParentPage  OnInit"); 
  10.           base.OnInit(e); 
  11.           //编写相应的代码防止SQL注入 
  12.           //System.Web.HttpContext.Current.Request.QueryString/Form 
  13.           //根据上下文对象来检测,以及做出相应的处理 
  14.           //以及其他一些内容的设置、控制等等 
  15.       } 
  16.  
  17.       protected override void OnLoad(EventArgs e) 
  18.       { 
  19.           Core.Trace.TraceInfo("UserParentPage  OnLoad"); 
  20.           base.OnLoad(e); 
  21.           //编写相应的代码对整体页面的控制 
  22.       } 
  23.   } 

(二)用户控件(子控件)的相关内容

  1. public partial class UserEventControl : System.Web.UI.UserControl 
  2.     public delegate void ChangedHandler(); 
  3.     public event ChangedHandler Changed; 
  4.     private void Page_Load(object sender, System.EventArgs e) 
  5.     { 
  6.         Core.Trace.TraceInfo("UserEventControl  OnLoad"); 
  7.         if (!Page.IsPostBack) 
  8.         { 
  9.             Core.Trace.TraceInfo("UserEventControl  OnLoad  !Page.IsPostBack==true"); 
  10.             SetContent(); 
  11.         } 
  12.     } 
  13.     private void SetContent() 
  14.     { 
  15.         int len =12,num = 2,perRowMaxCount=8;          
  16.         System.Text.StringBuilder table = new System.Text.StringBuilder();             
  17.         for (int i = 0; i <= num; i++) 
  18.         { 
  19.             table.Append(@"<table  bordercolor='black' width='100%'><tr align='left'>"); 
  20.             for (int j = 0; j < perRowMaxCount; j++) 
  21.             { 
  22.                 int p = i * perRowMaxCount + j; 
  23.                 if (p < len) 
  24.                 { 
  25.                     string paramValue ="param"+p.ToString(); 
  26.                     string showValue ="show"+p.ToString(); 
  27.                     table.Append(string.Format(@"<td width='12.5%'><a  href='javascript:__doPostBack(""{2}"",""{0}"")' CommandName=""{0}"" class='line'><font>{1}</font></a></td>", paramValue,showValue, lbtnShow.ClientID.Replace("_lbtnShow""$lbtnShow"))); 
  28.                 } 
  29.                 else 
  30.                 { 
  31.                     table.Append(string.Format(@"<td width='12.5%'></td>")); 
  32.                 } 
  33.             } 
  34.             table.Append(@"</tr></table>"); 
  35.         } 
  36.         lblShow.Text = table.ToString(); 
  37.     } 
  38.  
  39.     public string CurrentID 
  40.     { 
  41.         set 
  42.         { 
  43.             ViewState["CurrentID"] = value; 
  44.         } 
  45.         get 
  46.         { 
  47.             return (string)ViewState["CurrentID"]; 
  48.         } 
  49.     } 
  50.  
  51.     protected override void OnInit(EventArgs e) 
  52.     { 
  53.         Core.Trace.TraceInfo("UserEventControl  OnInit"); 
  54.         InitializeComponent(); 
  55.         base.OnInit(e); 
  56.     } 
  57.  
  58.     private void InitializeComponent() 
  59.     { 
  60.         this.lbtnShow.Click += new System.EventHandler(this.lbtnShow_Click); 
  61.         this.Load += new System.EventHandler(this.Page_Load); 
  62.     } 
  63.     /// <summary> 
  64.     /// 单击时将触发 
  65.     /// </summary> 
  66.     /// <param name="sender"></param> 
  67.     /// <param name="e"></param> 
  68.     private void lbtnShow_Click(object sender, System.EventArgs e) 
  69.     { 
  70.         Core.Trace.TraceInfo("UserEventControl  lbtnShow_Click"); 
  71.         CurrentID = Request.Form["__EVENTARGUMENT"];//获取回传值 
  72.         SetContent();//设置内容----因为有些内容被修改过,如样式什么的,本例忽略 
  73.         Changed();//触发事件 
  74.     } 

上面最主要的3点:
 (1)javascript:__doPostBack()和Request.Form["__EVENTARGUMENT"];__doPostBack()第一个参数必须用控件的name 而不是ID。控件名为将父控件ID用$符号连接起来的。第二个参数是传给控件的Value值。第一个参数对应 Request.Form["__EVENTTARGET"]; 第二个参数对应Request.Form["__EVENTARGUMENT"]。此函数是DOTNET 的服务器控件产生的,所以要使用此函数,必须整个页面上至少要有一个控件可以回传页面。其实,dotnet 服务器控件在页面上产生两个隐藏的控件一个名为__EVENTTARGET ,另一个名为__EVENTARGUMENT。

(2)ViewState视图状态保存的是页面级别的内容。CurrentID = Request.Form["__EVENTARGUMENT"];
(3)点击后将导致事件的触发(回传)。 Changed();

(三)页面的事件与委托处理

  1. public partial class Default : Core.UserParentPage 
  2.     protected void Page_Init(object sender, EventArgs e)  
  3.     { 
  4.         Core.Trace.TraceInfo("Default  OnInit"); 
  5.     } 
  6.  
  7.     protected void Page_Load(object sender, EventArgs e) 
  8.     { 
  9.         Core.Trace.TraceInfo("Default   Page_Load"); 
  10.         userEventControl.Changed+=new UserControl.UserEventControl.ChangedHandler(userEventControl_Changed); 
  11.     } 
  12.  
  13.     private void userEventControl_Changed()  
  14.     { 
  15.         Core.Trace.TraceInfo("Default   userEventControl_Changed"); 
  16.         
  17.         string id = userEventControl.CurrentID; 
  18.         ViewState["ID"] =id;//保存状态进行相应的处理 
  19.         lblShow.Text =id; 
  20.     } 

这一步最关键,利用userEventControl.Changed+=new UserControl.UserEventControl.ChangedHandler(userEventControl_Changed),当事件触发时,我们能够通过userEventControl_Changed()方法获取点击的value值,用视图状态保存该值,进而进行相应的操作(控制)。页面显示如下:

(四)跟踪文件为当前目录下的trace.txt文件

  1. public static class Trace 
  2.    { 
  3.         private static string logPath = HttpContext.Current.Request.PhysicalApplicationPath; 
  4.         public static void TraceInfo(string information) 
  5.         { 
  6.             string path = logPath + @"trace.txt"
  7.             string sqltemp = DateTime.Now.ToString("yyy-MM-dd hh:mm:ss fff") + ": " + information; 
  8.             FileStream fs = null
  9.             if (!File.Exists(path)) 
  10.             { 
  11.                 fs = File.Create(path); 
  12.                 fs.Close(); 
  13.             } 
  14.             StreamWriter sw = new StreamWriter(path, true, Encoding.UTF8); 
  15.             sw.WriteLine(sqltemp); 
  16.             sw.Close(); 
  17.         } 
  18.    } 

 在每个页面上的事件中增加自定义跟踪,可以发现如下情况:Init和Load都在每个控件上递归方式发生,但它们发生的顺序是相反的。每个子控件的Init与Unload事件在其容器引发相应的事件之前发生。容器的Load事件是在其子控件的Load事件之前发生。
trace.txt内容显示如下(生成页面的过程以及点击事件触发跟踪):
2010-11-23 02:26:29 828: UserEventControl OnInit
2010-11-23 02:26:29 828: UserParentPage OnInit
2010-11-23 02:26:29 828: Default OnInit
2010-11-23 02:26:29 828: UserParentPage OnLoad
2010-11-23 02:26:29 828: Default Page_Load
2010-11-23 02:26:29 828: UserEventControl OnLoad
2010-11-23 02:26:29 828: UserEventControl OnLoad !Page.IsPostBack==true
2010-11-23 02:26:29 828: UserEventControl OnLoad
2010-11-23 02:26:29 828: UserEventControl OnLoad !Page.IsPostBack==true
2010-11-23 02:26:31 171: UserEventControl OnInit
2010-11-23 02:26:31 171: UserParentPage OnInit
2010-11-23 02:26:31 171: Default OnInit
2010-11-23 02:26:31 171: UserParentPage OnLoad
2010-11-23 02:26:31 171: Default Page_Load
2010-11-23 02:26:31 171: UserEventControl OnLoad
2010-11-23 02:26:31 171: UserEventControl OnLoad
2010-11-23 02:26:31 171: UserEventControl lbtnShow_Click
2010-11-23 02:26:31 171: Default userEventControl_Changed

从前面的6句可以看出,子控件UserEventControl 的Init事件发生在UserParentPage 以及Default 的Init事件之前,而子控件UserEventControl 的Load事件发生在UserParentPage 以及Default 的Load事件之后。其中,父类UserParentPage 的事件发生在子类Default 的事件之前。

注:
2010-11-23 02:26:29 828: UserEventControl OnLoad
2010-11-23 02:26:29 828: UserEventControl OnLoad !Page.IsPostBack==true
2010-11-23 02:26:29 828: UserEventControl OnLoad
2010-11-23 02:26:29 828: UserEventControl OnLoad !Page.IsPostBack==true

这个地方明显有点不对劲,再反过去查看下子控件事件中的代码。发现  

  1. private void InitializeComponent() 
  2.     this.lbtnShow.Click += new System.EventHandler(this.lbtnShow_Click); 
  3.     this.Load += new System.EventHandler(this.Page_Load); 

多了这一行this.Load += new System.EventHandler(this.Page_Load); Load事件中再一次触发了子控件的Page_Load方法,因此注销掉该句。

到此我们再看一下跟踪文件中的内容(将原有记录全清空),如下所示:

  1. 2010-11-23 02:46:11 281: UserEventControl  OnInit 
  2. 2010-11-23 02:46:11 281: UserParentPage  OnInit 
  3. 2010-11-23 02:46:11 281: Default  OnInit 
  4. 2010-11-23 02:46:11 281: UserParentPage  OnLoad 
  5. 2010-11-23 02:46:11 281: Default   Page_Load 
  6. 2010-11-23 02:46:11 281: UserEventControl  OnLoad 
  7. 2010-11-23 02:46:11 281: UserEventControl  OnLoad  !Page.IsPostBack==true 
  8. 2010-11-23 02:46:13 265: UserEventControl  OnInit 
  9. 2010-11-23 02:46:13 265: UserParentPage  OnInit 
  10. 2010-11-23 02:46:13 265: Default  OnInit 
  11. 2010-11-23 02:46:13 265: UserParentPage  OnLoad 
  12. 2010-11-23 02:46:13 265: Default   Page_Load 
  13. 2010-11-23 02:46:13 265: UserEventControl  OnLoad 
  14. 2010-11-23 02:46:13 265: UserEventControl  lbtnShow_Click 
  15. 2010-11-23 02:46:13 281: Default   userEventControl_Changed 

这里就分成了2次操作,第1次为加载显示的过程(1-7句),第2次为点击获取相应的值的过程(8-15句)。过程是差不多的,仅仅多了一个回传事件。这与上面总结的是一致的。

总结

     通过父类、子类以及子控件之间的关系,加强对页面生命周期的理解,精简不必要的操作。通过事件和委托、视图状态能够很好的完成某些复杂的功能,具体应用本文将不再讲叙,仅仅是给读者一个引子。合理利用javascript:__doPostBack()和Request.Form["__EVENTARGUMENT"]能获得意想不到的效果。Init和Load都在每个控件上递归方式发生,但它们发生的顺序是相反的。每个子控件的Init与Unload事件在其容器引发相应的事件之前发生。容器的Load事件是在其子控件的Load事件之前发生。这个仅仅是本人以前实现的功能的一个精简版本,希望对各位有所帮助。

设为首页 | 加入收藏 | 网学首页 | 原创论文 | 计算机原创
版权所有 网学网 [Myeducs.cn] 您电脑的分辨率是 像素
Copyright 2008-2020 myeducs.Cn www.myeducs.Cn All Rights Reserved 湘ICP备09003080号 常年法律顾问:王律师