Monday, October 03, 2005

IsPostBack Issue and Workaround

The past couple of days, I have been working on a problem that I finally solved.

Suppose you created this really useful custom control class, and that you have been using this class on all sorts of pages with no problems. Then suppose that this class needs to be embedded in another control, that is embedded in another control. Everything still seems to be fine, until you find a bug. This bug, as it turns out, is a result of the dynamic built nature of your control. Your control displays a nifty list that also provides a search capability. Everything works fine until you search. It appears to work. Your list is generated, and the link buttons are all created just fine in the list. Then, you click one. Postback occurs, it goes awry. The button you clicked is not what the page thought you clicked. In fact, what it thought you clicked was actually the button that happened to be in the same location in the list prior to your search.

Well, the problem as you may have guessed, if you are .NET savvy, is that I rebound the data on the Load event for the page. This is typically a non-no unless you are building dynamic controls. In those cases, you have to rebind so that you rebuild the state of the control, so it can process events.

OK, so I remove that. It shouldn't be there. But, actually it should. I need to display an initial set of data when the page first loads. Ok, so I think, I can just check to see if this is a post back or not, right? Well, normally yes. But in my case, I couldn't. Here's why. In my case, the control that contains this list control is actually a dynamically loaded control that results from a click in another list in another control. Sound complicated? It is. So, what happens is by the time I get to this control, it is already in post-back mode, and will continue to be so from this point forward. But I really need a way to know that it is the first time this control has loaded.

Here's where the solution comes in. My Load event handler now looks like the following:

if (this.ViewState["firstTime"] == null)
{
    bindData();
    this.ViewState["firstTime"] = false;
}


What happens is now when the control loads, it checks for the existence of "firstTime" in the ViewState. If it's there, then it just goes on it's merry way. If it's not though, we are loading this control for the first time, so we bind our data, and then we set the ViewState indicating we are no longer in a first time state. The ViewState object persists as long as we are posting-back to this page, and once we are not, it is cleared. When the control is loaded again, it will be just like the first time.

No comments: