Page Event Lifecycle (Not So) Mysteries
For the past few hours I've been working on upgrading the Interscape Store to handle some new promotions we're doing. One of the features I've been wanting to add was the ability to see the cart's total change if you add a promotion to it. Right now, it's not possible because of a limitation in the Commerce framework that I'm using (XHEO|Commerce, it's pretty nifty, but not released yet), but I just finished coding a really elaborate workaround that seems to be doing the trick.
The problem is, I couldn't get the DataGrid footer to update when the page reloaded. After about 15 minutes of screwing around with it, I decided to add some page tracing information to the page, and turn tracing on. What I found confirmed a few things I should have known, but have taken for granted, and one thing I didn't.
Now, the Grid in question had 3 rows, so ItemDataBound was called 3 times. The last time is where the footer cell gets updated with the new Cart totals. The trace information is below:
aspx.page | Begin ProcessPostData | 0.034103 | 0.000056 |
aspx.page | End ProcessPostData | 0.034255 | 0.000152 |
Form Load Processing Started | 0.034616 | 0.000361 | |
ItemDataBound Processing Started | 0.034830 | 0.000215 | |
ItemDataBound Processing Finished | 0.034882 | 0.000051 | |
ItemDataBound Processing Started | 0.035119 | 0.000237 | |
ItemDataBound Processing Finished | 0.035177 | 0.000058 | |
ItemDataBound Processing Started | 0.035231 | 0.000054 | |
ItemDataBound Processing Finished | 0.035372 | 0.000141 | |
Form Load Processing Finished | 0.035758 | 0.000386 | |
aspx.page | Begin ProcessPostData Second Try | 0.035998 | 0.000240 |
aspx.page | End ProcessPostData Second Try | 0.036059 | 0.000061 |
aspx.page | Begin Raise ChangedEvents | 0.036099 | 0.000040 |
aspx.page | End Raise ChangedEvents | 0.036145 | 0.000045 |
aspx.page | Begin Raise PostBackEvent | 0.036206 | 0.000061 |
Promotion Processing Started | 0.036252 | 0.000046 | |
Promotion Added | 0.037015 | 0.000764 | |
Promotion Processing Finished | 0.037116 | 0.000101 | |
aspx.page | End Raise PostBackEvent | 0.037182 | 0.000066 |
So, what I should have remembered but didn't is that my databinding was taking place in the Form.Load event. What I didn't know (but in retrospect probably should have) is that the Form.Load event is processed way before the PostBack event. Because of this, my Grid thinks the state hasn't been changed, because the promotion control hasn't been added to the page yet (occurs in the button.Click event).
So, I thought I was SOL on this one, but it turns out that the XHEO Public Library has a nifty method in the Xheo.Web.WebUtilities namespace called “Refresh()”. Basically it refreshes the request without a postback event, which means that the Grid Databinding will get called again, and this time my ItemDataBinding routines get run.
Today's Lesson: When you can't figure out what's going on, add Trace.Warn(string) items to the beginning and end of each routine on your page. Sometimes it helps to see what's going on in the event lifecycle.
All this event goodness makes me want to finish the article I wrote almost a year ago that used the RaiseEvents method of the DataGrid class to show the event lifecycle of the DataGrid. Maybe I'll get around to it next week.