Archives / 2005 / August
  • Why don't callbacks send the latest values of the form fields?

    I've been getting this question a lot lately. Yes, it will stay that way and yes, it will confuse people.
    The reason for that is very complex but I'll try to explain briefly.
    First, you need to know that it's impossible to update the viewstate during a callback because contrary to postbacks, there can be multiple simultaneous callbacks which could cause an inconsistency or concurrency issue in the state.
    Now, if we sent the latest version of the form, because of that, change events would fire on every single callback, each of which could have side-effects.
    But there's worse. Some complex callback controls, like TreeView, need to manage their own client-side state (like the list of nodes that have been expanded client-side or using populate on demand). This client-side, control-specific state is kept in a hidden field that's used on the next postback to replay the changes and update the viewstate. Rehydrating the state from ViewState is cheap, replaying changes is not because that may involve multiple calls to a database.
    Again, if we sent the latest version of the form during a callback and if we want the state of the page to be consistent, the tree would replay all the changes that have been done client-side since the last postback, on every callback. That would result in an unacceptable performance drop.
    And you'll have the exact same problem with any complex data control that needs to maintain client-side state about the changes that occurred since the last postback. The ViewState can't be used for this state because it can't be updated during callbacks, so to maintain a consistent state, you need to replay the changes during the next postback, but not during each callback because the changes could add up pretty fast, growing the total number of operations to replay as an o(n^2) function of the number of callbacks.
    There are more intricate details involved but this is the big picture.
    The good news is that the advice here is simple: you need to package any form fields you need to use to determine your callback response into your callback parameter. To help you package multiple, strongly-typed pieces of information into the single string callback parameter, check out my RefreshPanel library.

    More details about that here.


  • How to output HTML at the end of a WebForm from code?

    With all this client-side activity that's going on lately, there's one particular need I've seen arise repeatedly. It is often useful to output contents at the end of a page (or at the end of the form, at least). The reasons why you would want to render contents not in the current position in the stream of the rendering page but at the end are diverse. One reason could be that you want only one instance of that contents on the page no matter how many controls require it. Another could be that you want controls to be able to add to a big chunk of data that you want to output in one piece at the end (that's a need we had in Atlas).


  • How to put a DIV over a SELECT in IE6?

    Everybody who tried to implement an HTML menu knows it: in Internet Explorer 6, there are some elements like SELECT that always appear in front of all other elements no matter what z-index you apply to them. Other elements that present the same problem are ActiveX controls (including Flash movies), OBJECT tags, plug-ins and iFrames. That's because these elements are implemented as windows whereas other elements are just drawn on the existing background window.