Dude, where's my checkbox?
Thomas, one of our users and the author of a soon to be released open-source survey tool, submitted this puzzle to me today.
He has a composite control that has a TextBox and a checked by default CheckBox as its child controls. He was wondering why, when in LoadPostData during a post back, his TextBox had its posted value available in the Text property, whereas the CheckBox was still in its default checked state.
Well, first of all, the new value of any control is not available during all stages of the page lifecycle. That's what the lifecycle is about, actually. In particular, there is no guaranty as to the state of any control during LoadPostData.
Now, why does the TextBox already have its state restored, whereas the checkbox is still in its default state? What's different in these two controls that would make them behave differently?
If you debug into this, the first thing you notice is that LoadPostData is called first for the checkbox, then for the composite control, and finally for the checkbox, no matter what the order of the controls in the control tree is.
This can look strange, but the answer lies in the private Page.ProcessPostData method (Reflector is your friend if you really want to look at the source code). This method starts by scanning each field in the POST data. For each field, it looks for a control with the same unique ID and calls LoadPostData on it if it finds it.
Then, and only then, it scans the list of controls that registered for postback treatment but have no POST field, and calls LoadPostData on them.
Of course, an unchecked checkbox does not send a POST field at all, which is where it's different from a TextBox that returns an empty field if it's empty.
And this explains why LoadPostData is called on the checkbox after it's called on our composite control, and the checked state of the checkbox is wrong at this point.
So what can you trust from LoadPostData? Well, the method has a postCollection argument (some kind of copy of Request.Form) that is perfectly safe and clean to use, and this is where you should get your state data from.