ASP.NET 中的视图状态和控件 [英] Viewstate and controls in ASP.NET

查看:23
本文介绍了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 是从 Page 的 OnInit 加载的,那么他的视图状态将在 OnLoad 中可用.usercontrolA 从其 OnInit 加载的所有其他控件,将在其 OnLoad 中准备好其视图状态.
  2. 如果 usercontrolA 是从 Page 的 OnLoad 加载的,那么他的 viewstate 将在 OnPreRender 中可用.usercontrolA 从其 OnLoad 加载的所有其他控件,将在其 OnPreRender 中提供其视图状态.
  3. 如果 usercontrolA 从页面的事件(例如:按钮单击.事件在 OnLoad 之后和 OnPreRender 之前触发)加载,则他的视图状态将不可用.usercontrolA 加载的所有其他控件的视图状态都将不可用.
  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 加载控件时,控件是否无法在 OnPreRender 阶段之前获取其视图状态?

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?

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

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.

感谢任何建议和/或链接.

Any suggestions and/or links are appreciated.

推荐答案

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

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)

Label为例,它覆盖LoadViewState,直接从ViewState中拉取它的Text属性.文本框类似.因此,根据我的阅读,应该可以随时添加,然后访问 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.

这篇关于ASP.NET 中的视图状态和控件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆