视图状态和ASP.NET控件

问题描述:

我发布了一个问题前两天关于视图状态和运行一些测试我得出了一些结论/后的结果。基于这些结果,我有几个问题,以别人会怎么做某些事情。

I posted a question a couple of days ago about viewstate and after running some tests I have come to some conclusions/results. Based on these results I have a few questions as to how someone would do certain things.

下面是我的测试,我跑的结果:

Here are the results of my tests that I ran:


  1. 如果usercontrolA从的OnInit 加载页面,那么他的视图状态会在的OnLoad 可用。所有其他控件,从它usercontrolA负载的的OnInit ,都会有自己的ViewState准备在他们的的OnLoad

  2. 如果usercontrolA从页面的OnLoad 加载,那么他的视图状态将可在在preRender 。所有其他控件,从它usercontrolA负载的的OnLoad ,就获得了他们的ViewState在他们的在preRender

  3. 如果usercontrolA是从事件时加载(例如:按一下按钮事件触发的OnLoad 和前在preRender后$ C页面$ C>),那么他的视图状态将无法使用。这usercontrolA loades不会有他们的ViewState提供的所有其他控件。

  1. If usercontrolA is loaded from OnInit of a Page, then his viewstate will be available in OnLoad. All other controls that usercontrolA loads from it's OnInit, will have their viewstate ready in their OnLoad.
  2. If usercontrolA is loaded from OnLoad of a Page, then his viewstate will be available in OnPreRender. All other controls that usercontrolA loads from it's OnLoad, will have their viewstate available in their OnPreRender.
  3. If usercontrolA is loaded from an event (Example: button click. Events fire after OnLoad and before OnPreRender) of a Page, then his viewstate will not be available. All other controls that usercontrolA loades will not have their viewstate available.

因此​​,在一个完美的世界里,你将永远载入使用情况#1所有控件,使自己的视图状态可以用它们的的OnLoad 。不幸的是,当你需要从一个按钮,点击或从的OnLoad 负载的控制,有没有办法之前控制来获得它的视图状态在preRender 阶段?

So in a perfect world you would always load all controls using situation #1, so that their viewstate is available on their OnLoad. Unfortunately when you need to load a control from a button click or from a OnLoad, is there no way for control to get its viewstate before OnPreRender stage?

我读了一堆关于视图状态的文章,以为我的理解是,但它加载它加载其他用户控件用户控件我目前的应用程序的工作,我有能够让我的叶视图状态(最后一个真正的困难时期链)用户控件。

I have read a bunch of articles on viewstate and thought I understood it, but working on my current application which loads usercontrols which load other usercontrols, I am having a real hard time with being able to get viewstate on my leaf (last in the chain) usercontrol.

任何建议和/或链接AP preciated。

Any suggestions and/or links are appreciated.

这是公认的做法来加载在OnInit的动态控件,使他们得到全面控制生命周期。我不知道我特别理解你的处境,虽然 - 如果你加载基于点击一个按钮控制,为什么会在这一点上有视图状态?在接下来的OnInit的,你应该加载控制的再次的(我通常使用一个页面级视图状态的项目来跟踪一个特定的控制需要被加载),因此它可以通过从视图状态恢复的。是这样的:

It is accepted practice to load dynamic controls in OnInit, so that they get the full control lifecycle. I'm not sure I particularly understand your situation though - if you're loading a control based on a button click, why would it have viewstate at that point? On the next OnInit, you should load the control again (I usually use a page level Viewstate item to track that a particular control needs to be loaded) so that it can restore from Viewstate. Something like:

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;
   }
}

稍微更有趣的一点,虽然,是根据追赶事件 - 它真的不应该的问题。动态加载控件调用堆栈看起来是这样的:

The slightly more interesting bit, though, is that according to catch-up events - it really shouldn't matter. The callstack for dynamically loading a control looks something like:

Control.Controls.Add(Control)
   Control.AddedControl(Control)
      Control.LoadViewStateRecursive(object)
          Control.LoadViewState(object)

标签作为一个例子,它会覆盖 LoadViewState 和拉它的文本直接从ViewState属性。文本框是相似的。因此,通过我的阅读,应该确定在任何时候添加,然后访问的ViewState。这似乎并没有被摇摆凭我的经验,虽然如此,进一步调查似乎有必要。

Taking Label as an example, it overrides LoadViewState and pulls it's Text property directly from ViewState. TextBox is similar. So, by my reading, it should be OK to add at any point, and then access ViewState. That doesn't seem to be jive with my experience, though, so further investigation seems warranted.