Page对象在SaveState阶段都做了什么?
当页面运行至SaveState阶段时,将调用其自身SaveAllState()方法,在这个方法内部,做了两件事,第一件事就是保存控件状态,即ControlState,第二件事就是保存控件视图状态,即ViewState。ControlState我们放到以后再说,今天说说ViewState,在SaveAllState()这个方法内部,调用控件的SaveViewStateRecursive()方法,在这个方法的内部,调用控件的SaveViewState方法,下面列出该方法的源码:
1 // Answer any state this control or its descendants want to save on freeze.
2 // The format for saving is Triplet(myState, ArrayList childIDs, ArrayList childStates),
3 // where myState or childStates and childIDs may be null.
4 internal object SaveViewStateRecursive() {
5 if (flags[disableViewState])
6 return null;
7
8 object adapterState = null;
9 if (_adapter != null) {
10 adapterState = _adapter.SaveAdapterViewState();
11 }
12
13 object controlSavedState = SaveViewState();
14
15 ArrayList childStates = null;
16 if (HasControls()) {
17 ControlCollection occasionalFieldControls = _occasionalFields.Controls;
18 int occasionalFieldControlCount = occasionalFieldControls.Count;
19
20 bool useId = LoadViewStateByID;
21 for (int i = 0; i < occasionalFieldControlCount; i++) {
22 Control child = occasionalFieldControls[i];
23 object childState = child.SaveViewStateRecursive();
24 if (childState != null) {
25 if (childStates == null) {
26 childStates = new ArrayList(occasionalFieldControlCount);
27 }
28
29 if (useId) {
30 child.EnsureID();
31 childStates.Add(child.ID);
32 }
33 else {
34 childStates.Add(i);
35 }
36 childStates.Add(childState);
37 }
38 }
39 }
40
41 if (_adapter != null) {
42 if ((controlSavedState != null) || (adapterState != null) || (childStates != null)) {
43 return new Triplet(controlSavedState, adapterState, childStates);
44 }
45 }
46 else {
47 if ((controlSavedState != null) || (childStates != null)) {
48 return new Pair(controlSavedState, childStates);
49 }
50 }
51
52 return null;
53 }
2 // The format for saving is Triplet(myState, ArrayList childIDs, ArrayList childStates),
3 // where myState or childStates and childIDs may be null.
4 internal object SaveViewStateRecursive() {
5 if (flags[disableViewState])
6 return null;
7
8 object adapterState = null;
9 if (_adapter != null) {
10 adapterState = _adapter.SaveAdapterViewState();
11 }
12
13 object controlSavedState = SaveViewState();
14
15 ArrayList childStates = null;
16 if (HasControls()) {
17 ControlCollection occasionalFieldControls = _occasionalFields.Controls;
18 int occasionalFieldControlCount = occasionalFieldControls.Count;
19
20 bool useId = LoadViewStateByID;
21 for (int i = 0; i < occasionalFieldControlCount; i++) {
22 Control child = occasionalFieldControls[i];
23 object childState = child.SaveViewStateRecursive();
24 if (childState != null) {
25 if (childStates == null) {
26 childStates = new ArrayList(occasionalFieldControlCount);
27 }
28
29 if (useId) {
30 child.EnsureID();
31 childStates.Add(child.ID);
32 }
33 else {
34 childStates.Add(i);
35 }
36 childStates.Add(childState);
37 }
38 }
39 }
40
41 if (_adapter != null) {
42 if ((controlSavedState != null) || (adapterState != null) || (childStates != null)) {
43 return new Triplet(controlSavedState, adapterState, childStates);
44 }
45 }
46 else {
47 if ((controlSavedState != null) || (childStates != null)) {
48 return new Pair(controlSavedState, childStates);
49 }
50 }
51
52 return null;
53 }
第5行代码,需要引起我们的注意,flags[disableViewState]和控件的EnableViewState属性想对应。
下边用一个简单的示例,来描述一下页面是如何递归保存其内部控件的视图状态:
Code
上边的代码列出了一个简单页面和其对应的cs页面代码。
这个页面对应的控件树为:
下边列出Page、HtmlForm、Literal这三个主要对象的顺序图: