F
Ferret
I've found what seems to be a nasty bug in the DataGrid and Repeater
classes. If CreateChildControls gets called before LoadViewState,
ViewState fails to map and you end up with nothing on a Postback.
Please try the following test, and let me know if you can reproduce
this:
- Create a custom DataGrid or Repeater class that does nothing but
derive from one of the above and gives a place to put breakpoints in
overriden handlers
- Create a simple test case on a WebForm. I use template columns, but
BoundColumns might work as well.
- Create something in your DataGrid/Repeater that posts back, like a
LinkButton in a HeaderTemplate.
- Only DataBind if it's not a PostBack
- Put an EnsureChildControls at the beginning of OnInit in your custom
DataGrid/Repeater
When I click on the LinkButton, I get no output at all. Put
breakpoints in OnInit, LoadViewState, and CreateChildControls of your
custom class. If CreateChildControls gets called before LoadViewState,
nothing maps and there's no output. Now, if you take
EnsureChildControls out of OnInit, and your test is simple, you'll see
LoadViewState happen before CreateChildControls and everything will
work wonderfully.
Why is that? That's exactly opposite from everything I've learned so
far concerning server controls. Usually, the earlier you re-create all
your controls the better for mapping events, ViewState, etc. Why are
these framework control different? I can't avoid having my controls
created early in my big application because I usually put
EnsureChildControls in all my Properties, etc, like I thought was good
practice. Are DataGrids and Repeaters doomed to fail with these
practices?
I've considered finding a workaround. I even considered calling
LoadViewState at the beginning of CreateChildControls on a PostBack,
but I haven't tried it yet because I don't know if it would be safe to
do it even if it's possible. Any help or input on why this is
happening or any hacks or workarounds will be very welcome.
classes. If CreateChildControls gets called before LoadViewState,
ViewState fails to map and you end up with nothing on a Postback.
Please try the following test, and let me know if you can reproduce
this:
- Create a custom DataGrid or Repeater class that does nothing but
derive from one of the above and gives a place to put breakpoints in
overriden handlers
- Create a simple test case on a WebForm. I use template columns, but
BoundColumns might work as well.
- Create something in your DataGrid/Repeater that posts back, like a
LinkButton in a HeaderTemplate.
- Only DataBind if it's not a PostBack
- Put an EnsureChildControls at the beginning of OnInit in your custom
DataGrid/Repeater
When I click on the LinkButton, I get no output at all. Put
breakpoints in OnInit, LoadViewState, and CreateChildControls of your
custom class. If CreateChildControls gets called before LoadViewState,
nothing maps and there's no output. Now, if you take
EnsureChildControls out of OnInit, and your test is simple, you'll see
LoadViewState happen before CreateChildControls and everything will
work wonderfully.
Why is that? That's exactly opposite from everything I've learned so
far concerning server controls. Usually, the earlier you re-create all
your controls the better for mapping events, ViewState, etc. Why are
these framework control different? I can't avoid having my controls
created early in my big application because I usually put
EnsureChildControls in all my Properties, etc, like I thought was good
practice. Are DataGrids and Repeaters doomed to fail with these
practices?
I've considered finding a workaround. I even considered calling
LoadViewState at the beginning of CreateChildControls on a PostBack,
but I haven't tried it yet because I don't know if it would be safe to
do it even if it's possible. Any help or input on why this is
happening or any hacks or workarounds will be very welcome.