ASP.NET中的Viewstate和控件

Blu*_*eon 8 c# asp.net viewstate user-controls

我几天前发布了一个关于viewstate的问题,在运行了一些测试后,我得出了一些结论/结果.基于这些结果,我有一些关于某人如何做某些事情的问题.

以下是我运行的测试结果:

  1. 如果usercontrolA是从OnInitPage 加载的,那么他的viewstate将可用OnLoad.usercontrolA从其加载的所有其他控件OnInit将使其viewstate准备就绪OnLoad.
  2. 如果usercontrolA是从OnLoadPage 加载的,那么他的viewstate将可用OnPreRender.usercontrolA从其加载的所有其他控件OnLoad将在其中提供其viewstate OnPreRender.
  3. 如果usercontrolA是从一个页面的事件(例如:按钮单击.事件触发OnLoad之前和之后OnPreRender)加载的,那么他的视图状态将不可用.usercontrolA loades的所有其他控件都不会提供其viewstate.

因此,在完美的世界中,您总是会使用情境#1加载所有控件,以便他们的视图状态可用OnLoad.不幸的是,当你需要从一个点击按钮或从负载的控制OnLoad,是有没有办法控制之前得到它的ViewState的OnPreRender阶段?

我已经在viewstate上阅读了一堆文章并认为我理解它,但是在我当前的应用程序上加载加载其他用户控件的usercontrols,我真的很难在我的叶子上获得viewstate(最后在链中) )usercontrol.

任何建议和/或链接表示赞赏.

Mar*_*ett 3

在 OnInit 中加载动态控件是公认的做法,以便它们获得完整的控件生命周期。我不确定我是否特别理解你的情况 - 如果你要加载基于按钮单击的控件,为什么它此时会有视图状态?在下一个OnInit上,您应该再次加载该控件(我通常使用页面级 Viewstate 项来跟踪需要加载的特定控件),以便它可以从 Viewstate恢复。就像是:

class Default : Page {
   enum LoadedControl { Textbox, Label, GridView }

   override OnInit() {
      if (IsPostback) {
        var c = Viewstate["LoadedControl"] as LoadedControl;
        if (c != null) LoadDynamicControl(c);
      }
   }

   void Button_Click() {
     var c = (LoadedControl)Enum.Parse(typeof(LoadedControl), ddl.SelectedValue);
     LoadDynamicControl(c);
   }

   void LoadDynamicControl(LoadedControl c) {
     switch (c) {
        case LoadedControl.Textbox:
           this.ph.Controls.Add(new Textbox());
           break;
        ...
     }

     ViewState["LoadedControl"] = c;
   }
}
Run Code Online (Sandbox Code Playgroud)

不过,更有趣的是,根据追赶事件,这实际上并不重要。动态加载控件的调用堆栈如下所示:

Control.Controls.Add(Control)
   Control.AddedControl(Control)
      Control.LoadViewStateRecursive(object)
          Control.LoadViewState(object)
Run Code Online (Sandbox Code Playgroud)

举Label个例子,它直接从 ViewState 重写LoadViewState并提取它的Text属性。文本框类似。因此,根据我的阅读,应该可以在任何点添加,然后访问 ViewState。不过,这似乎与我的经验并不相符,因此似乎有必要进行进一步调查。