欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

asp.net 动态创建TextBox控件及状态数据如何加载

程序员文章站 2024-03-06 12:19:07
接着上文asp.net textbox的textchanged事件你真的清楚吗? 这里我们来说说状态数据时如何加载的。虽然在control中有调用状态转存的方法,但是这里有...

接着上文asp.net textbox的textchanged事件你真的清楚吗? 这里我们来说说状态数据时如何加载的。
虽然在control中有调用状态转存的方法,但是这里有一个判断条件 if (_controlstate >= controlstate.viewstateloaded) 一般的get请求这里的条件是不满足的。

复制代码 代码如下:

internal enum controlstate
{
constructed,
frameworkinitialized,
childreninitialized,
initialized,
viewstateloaded,
loaded,
prerendered
}

我们知道在page的processrequest中this.controlstate = controlstate.frameworkinitialized;processrequestmain方法中在init后有调用this.initrecursive(null);在这个方法里面有这么一句_controlstate = controlstate.initialized;,在loadallstate()方法中有这么一句 base.loadviewstaterecursive(second.second);,而loadviewstaterecursive中又有_controlstate = controlstate.viewstateloaded这句带代码,所以我们在page_load中动态条件控件时, if (_controlstate >= controlstate.viewstateloaded)条件成立,如图:

asp.net 动态创建TextBox控件及状态数据如何加载

所以在运行this.form1.controls.add(txt);这句以前,txt的值为demo1,

如图

asp.net 动态创建TextBox控件及状态数据如何加载


但是运行以后之就发生变化了:

asp.net 动态创建TextBox控件及状态数据如何加载

当然这里的txt.text值也是我上次post过来的旧值,新值是在控件的loadpostdata方法中重新绑定。在默认的loadviewstaterecursive方法中有一个很重要的判断

复制代码 代码如下:

internal void loadviewstaterecursive(object savedstate) {
// nothing to do if we have no state
if (savedstate == null || flags[disableviewstate])
return;

。。。。。。。

_controlstate = controlstate.viewstateloaded
}

大家看到我上面是一个custtextboxt : textbox控件,如果我们直接添加textbox控件的话,那么着这里的txt.text一直都是demo1,可见控件动态添加的时候是否加载状态数据与状态数据的保存有关。而状态数据的保存主要就是saveviewstate完成的,这里我第一次post的时候saveviewstate返回数据:

asp.net 动态创建TextBox控件及状态数据如何加载

所以第二次能取到上次post过来的数据。

其中与saveviewstate有关的方法主要有:

复制代码 代码如下:

public class textbox : webcontrol, ipostbackdatahandler, ieditabletextcontrol {
protected override object saveviewstate() {
if (savetextviewstate == false) {
viewstate.setitemdirty("text", false);
}
return base.saveviewstate();
}
private bool savetextviewstate {
get {
//


// must be saved when
// 1. there is a registered event handler for selectedindexchanged
// 2. control is not enabled or visible, because the browser's post data will not include this control
// 3. the instance is a derived instance, which might be overriding the ontextchanged method

if (textmode == textboxmode.password) {
return false;
}

if ((events[eventtextchanged] != null) ||
(isenabled == false) ||
(visible == false) ||
(readonly) ||
(this.gettype() != typeof(textbox))) {
return true;
}

return false;
}
}

}
public class webcontrol : control, iattributeaccessor {
protected override object saveviewstate() {
pair mystate = null;

// save values cached out of view state
if (_webcontrolflags[disableddirty]) {
viewstate["enabled"] = !flags[iswebcontroldisabled];
}

if (controlstylecreated) {
// the style shares the statebag of its owner webcontrol
// call saveviewstate to let style participate in state management
controlstyle.saveviewstate();
}

object basestate = base.saveviewstate();
object astate = null;
if (attrstate != null) {
astate = attrstate.saveviewstate();
}

if (basestate != null || astate != null) {
mystate = new pair(basestate, astate);
}
return mystate;
}
}
public class control : icomponent, iparseraccessor, iurlresolutionservice, idatabindingsaccessor, icontrolbuilderaccessor, icontroldesigneraccessor, iexpressionsaccessor {
protected virtual object saveviewstate() {
// save values cached out of view state
if (flags[visibledirty]) {
viewstate["visible"] = !flags[invisible];
}
if (flags[validaterequestmodedirty]) {
viewstate["validaterequestmode"] = (int)validaterequestmode;
}
if (_viewstate != null)
return _viewstate.saveviewstate();

return null;
}
}
public sealed class statebag : istatemanager, idictionary {
internal object saveviewstate() {
arraylist data = null;
if (bag.count != 0) {
idictionaryenumerator e = bag.getenumerator();
while (e.movenext()) {
stateitem item = (stateitem)(e.value);
if (item.isdirty) {
if (data == null) {
data = new arraylist();
}
#if objectstateformatter
data.add(new indexedstring((string)e.key));
#else
data.add(e.key);
#endif
data.add(item.value);
}
}
}

return data;
}
}

到这里我们知道保存状态信息主要是在statebag 的saveviewstate方法中,这里有一个检查  if (item.isdirty) ,在textbox的saveviewstate方法中有一个判断
复制代码 代码如下:

if (savetextviewstate == false) {
viewstate.setitemdirty("text", false);
}

与它的savetextviewstate 属性有关。

那么我们可以总结一下:动态创建的控件默认是在被添加的时候加载器状态数据,如果是静态添加的数据那就是loadallstate来处理状态数据的加载。状态数据的加载与控件的saveviewstate密切相关,如果该方法的返回值为null既没有状态信息,那也不需要加载什么状态信息了。