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.