我们平时所见到的web服务器控件,一般而言,其直接的基类,不是WebControl就是Control,我们今天说说Control的SaveViewState方法,这个方法的源码如下:
1
// Save modified state the control would like restored on the postback.
2
// Return null if there is no state to save.
3
4
}
2
3
4
第12行代码判断控件是否可见,第15行代码判断_viewState是否为null,如果在某一个控件中,所有的操作中都没有使用控件本身的ViewState属性,那么_viewState就是null,这种情况一般是不存在的。如果_viewState不为null,由于_viewState对象的类型是StateBag,则调用StataBag.SaveViewState。
1
private IDictionary bag;
2
2
1
}
通过上边的代码可以看出,SateBag.SaveViewState方法中的bag是HybridDictionary类型的实例,HybridDictionary类型实现了 IEnumerable接口,我们可以使用循环算法,依次取出其中的元素,如果有如何条件的元素,他们将会被保存在data对象里边,然后返回data对象。至此,控件的ViewState保存完毕。
这里边有一个关键的地方,那就是StateBag的IsDirty属性。
IsDirty属性和我们平时使用的ViewState有什么关系呢?默认情况下,IsDirty属性为false,它是怎么变成true的呢?要理解这些,请看下边的代码:
1
从上边两段代码可以看出,我们用上边的代码对Literal控件的Text属性赋值,相当于ViewState["Text"] = "Hello World!";,我们前边已经分析过,ViewState属性是StateBag类型的对象,StateBag的this属性源码为:
1
Code
2
}
StateBag.Add方法源码:2
1
Code
2
}
2
上边两段代码都不复杂,有一个地方需要我们注意,就是StateBag的Add方法,我们可以看到if(item != null && marked)条件成立的话,这个item的IsDirty属性就被赋值为true,item不为null这个好理解,marked是怎么成为true的呢,默认情况下,这个字段的值是false。
要理解这点,就要从页面的生命周期开始说起,页面在"Begin Init"阶段,调用Control.InitRecursive(null)方法,在这个方法的内部,调用Control.TrackViewState()方法,下边列出Control.TrackViewState()方法的源码:
从上边两段代码,可以看出,我们前边提到的marked字段,在这个方法中被赋值为true了。