zoukankan      html  css  js  c++  java
  • aspx页面的生存周期(转)

    aspx页面的生存周期
    1. PreInit()
             在这个页面级的事件中,所有在设计时创建的控件都将被用默认值做初始化。例如,如果你有一个Text属性值为“Hello”的TextBox控件,则此时这个属性被设置。我们也可以在这里动态的创建控件。
             这个事件仅仅发生在页级别的类中,用户控件和母版页没有这个事件。
             下面的代码示例了如何重写这个方法以增加你的自定义代码
             protected override void OnPreInit(EventArgs e)      
             {
                 //custom code           
                 base.OnPreInit(e);
             }
             注意,我们只能在PreInit()事件中动态的设置themes,且应该在PreInit()事件或该事件之前加载母版页。

    2. OnInit()
             在这个事件里,我们能读出控件的属性(在设计模式中设置的)。但是我们不能读出用户设置的值,因为得到用户设置的值是在LoadPostData()事件被激发之后。不过在这个事件中我们可以得到POST数据,如下
             string selectedValue = Request.Form[controlID].ToString();

    3. LoadViewState
             这个事件仅仅在回发之后被激发(IsPostBack == true)。在这个事件中runtime从隐藏域中分解出view state并加载到所有启用了view state的控件。

    4. LoadPostBackData
             这个事件也仅仅是在回发之后被激发。
             在这个事件里实现了IPostBackDataHandler接口的控件从HTTP的POST数据中得到值。注意,textbox控件不能从view state中获得值,而是在此事件中从POST数据中获得值。所以即使有些控件没有启用view state,只要它实现了IPostBackDataHandler接口就可以从HTTP的POST数据中得到值。
             另一个重要的知识点是如果我们有一个DropDownList控件并动态的给它增加一些选择项,那么runtime将不能得到这些值除非启用了view state(即使控件继承自IPostBackDataHandler接口)。这个原因就是在HTTP的POST数据中的每一个控件只能有一个值,并且POST数据中的所有值都不会被保存,除了使用view state。

    5. Page_Load
             这是最常用的方法了,而且是一些开发新手放置他们代码的第一个地方,有些新手们往往认为这就是Page类第一个触发的方法。这个方法是混淆我们Page生存周期的罪魁祸首之一。
             注意:如果页里有任何用户控件的话,那么用户控件的Load方法将在页类的Load方法之后被触发。除了Init()和Unload()之外的所有事件都是从最外面到最里面被激发的,所以页的Page_Load()之后,页内的其它控件的Load方法才被触发。

    6. Control Event Handlers
             事件处理(比如像Button1_Click()之类的)是定义在ASPX页面中的,有一些开发人员认为当单击一个按钮后会立即出发Button_Click() ,他们忘了在这个事件触发之前首先要触发Page_Load。

    7. PreRender
             如果我们想改变某一个控件的值,这是最后的机会了

    8. SaveViewState
             控件的ViewState被存储在form的隐藏域中

    9. Render
             呈现页面和控件

    10. Unload
             这是最后的清理操作


    动态控件
             现在我们已经知道了页的生存周期的重要事件,接下来让我们关注一下如何创建以及保持动态生成控件的状态。有的时候我们需要动态的生成控件,比如我原来管理的一个酒店预订的项目,用户在一个TextBox里输入房间号,根据这个值动态的生成一个用户控件来显示该房间的详细信息。
             开发人员虽然能动态的生成用户控件,但是却不能保存用户控件的状态。当我看了代码后,他们把生成控件的代码写到了Button的Click事件里。根据我们上面所讨论的,Button_Click()在LoadViewState()和LoadPostData()之后触发,而控件的值是要在view state或POST数据中取得的。
             所以除非在Page_Init()或Pre_Init()方法里重新创建控件(它们发生在LoadViewState和LoadPostData之前),这样就可以在下一个事件里获得控件的值。
             现在,如果把代码写到Page_Init()事件里的话,将不能得到用户在TextBox(它是一个静态控件)里输入的值。原因就在于这是Page_Init()事件,控件的值被初始化为它们设计时的默认值,而不会得到用户输入的值。
             所以如果要在这里访问到用户输入的值话只有一个办法,就是从POST数据中取值。代码如下
             protected override void OnInit(EventArgs e)   
             {
                 // 通过Post数据得到用户在TextBox里输入的值
                 string selectedValue ;
                 if(Request.Form["txtNoOfRooms"] != null)              
                     selectedValue = Request.Form["txtNoOfRooms"].ToString();
              
                 // 动态生成控件的代码
                 base.OnInit(e);
             }

             如果你在Page_Load事件里创建一个动态控件,并把它添加到PlaceHolder或Panel里(要打开view state),那么动态控件将会维持它的状态,即使它不是在Page_Init()中创建的,为什么?
             原因就是控件一旦被添加到页的控件树里,TrackViewState()方法就负责跟踪其状态。只要控件被添加到控件树里,这个方法就会被自动的触发。因为这个原因,对控件的任何修改(如添加item之类的)都应该在动态控件被添加到页的控件树之后来做,否则其状态将丢失。请看如下代码
             protected void Page_Load(object sender, EventArgs e)
             {
                 // 创建一个DropDownList
                 DropDownList d = new DropDownList();
       
                 // TrackViewState()方法将被触发去跟踪这个DropDownList的状态,所以其状态将被保持
                 PlaceHolder1.Controls.Add(d);

                 if (!IsPostBack)
                 {
                     d.Items.Add("test1");
                     d.Items.Add("test2");
                 }
             }

             下面的代码则不会保持动态控件的状态
             protected void Page_Load(object sender, EventArgs e)
             {
                 // 动态创建一个控件
                 DropDownList d = new DropDownList();
                 if (!IsPostBack)
                 {
                     d.Items.Add("test1");
                     d.Items.Add("test2");
                 }
       
                 // "test1"和"test2"值将丢失
                 PlaceHolder1.Controls.Add(d);
             }

  • 相关阅读:
    dpkg 被中断,您必须手工运行 sudo dpkg –configure -a 解决此问题
    运行wpscan报错Could not find 'nokogiri' (~> 1.8.0)
    理解:jar和war的区别
    AcWing3494. 国际象棋(状压DP)
    AcWing3422. 左孩子右兄弟(树形DP)
    python命名空间
    mysql日志大量报错“original commit timestamp is more recent than the immediate commit timestamp”
    python模块导入
    Centos-Docker镜像制作
    python面向对象之封装
  • 原文地址:https://www.cnblogs.com/huangyoum/p/1728141.html
Copyright © 2011-2022 走看看