asp.net 动态创建TextBox控件及状态数据如何加载
程序员文章站
2024-03-05 07:58:48
接着上文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)条件成立,如图:
所以在运行this.form1.controls.add(txt);这句以前,txt的值为demo1,
如图
但是运行以后之就发生变化了:
当然这里的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返回数据:
所以第二次能取到上次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既没有状态信息,那也不需要加载什么状态信息了。