查看ASP.NET中的状态和控件
本文关键字:状态 控件 ASP NET 查看 | 更新日期: 2023-09-27 18:22:04
几天前我发布了一个关于viewstate的问题,在运行了一些测试后,我得出了一些结论/结果。根据这些结果,我有几个问题,关于某人将如何做某些事情。
以下是我运行的测试结果:
- 如果从页面的
OnInit
加载usercontrolA,则他的视图状态将在OnLoad
中可用。usercontrolA从其OnInit
加载的所有其他控件的视图状态都将在其OnLoad
中就绪 - 如果从页面的
OnLoad
加载usercontrolA,那么他的视图状态将在OnPreRender
中可用。usercontrolA从其OnLoad
加载的所有其他控件的视图状态都将在其OnPreRender
中可用 - 如果从页面的事件(例如:按钮点击。事件在
OnLoad
之后和OnPreRender
之前触发)加载usercontrolA,则他的视图状态将不可用。usercontrolA加载的所有其他控件的视图状态都不可用
因此,在一个完美的世界中,您总是使用情形#1加载所有控件,以便它们的视图状态在其OnLoad
上可用。不幸的是,当您需要从按钮单击或从OnLoad
加载控件时,控件是否无法在OnPreRender
阶段之前获得其视图状态?
我读了很多关于viewstate的文章,认为我理解它,但在我当前加载用户控件和加载其他用户控件的应用程序上工作时,我很难在我的叶子(链中的最后一个)用户控件上获得viewstate。
欢迎提供任何建议和/或链接。
我认为我不能添加本文没有涉及的任何内容。
请特别查看生命周期事件部分。
http://msdn.microsoft.com/en-us/library/ie/ms178472.aspx
在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;
}
}
不过,更有趣的一点是,根据追赶事件,这真的不重要。用于动态加载控件的调用堆栈看起来像:
Control.Controls.Add(Control)
Control.AddedControl(Control)
Control.LoadViewStateRecursive(object)
Control.LoadViewState(object)
以Label
为例,它覆盖LoadViewState
,并直接从ViewState中提取其Text
属性。TextBox与此类似。因此,根据我的阅读,应该可以在任何时候添加,然后访问ViewState。不过,这似乎与我的经历不符,所以进一步的调查似乎是有必要的。
我很惊讶,但对您的结果很感兴趣。当我使用动态控件时,我总是将它们添加到Page_Init
中。其他任何东西都不起作用。但你是对的——如果你是在点击按钮时添加它们,你该怎么做呢。
我找到的唯一方法是在PageInit
上检查Request.Form("__EVENTTARGET")
集合。它包含触发回发的控件的控件ID,例如单击按钮。当然,它将由它出现的命名容器限定。一旦你用这种方法识别了"事件",你就可以添加你想要的控件。
这当然有点古怪,但这是我做这些事情的唯一方法。它确实有效。
有趣的是,如果在Page_Load
添加控件,ViewState
在PreRender
上可用。但正如上面的链接所表明的那样,现在帮助你已经太晚了。控件状态在加载循环期间重新水合。如果它不在那里,那么你的控制状态或动态控制就会消失。
您是否尝试使用LoadComplete
事件?
将此事件用于需要加载页面上所有其他控件的任务。
这是在PageLoad
和所有事件(ButtonClick等)之后触发的,因此您的UserControls加载在Button Click事件中,并且在LoadComplete
中它们的ViewState已经初始化。