Saturday, November 29, 2003


Source: Kirk Allen Evans' Blog

As several noted regarding the PDC pre-conference session “.NET: The XML And Web Services Perspective“, the point was made that global type declarations should be used in XML Schemas to avoid duplicate declarations without inferring context.  There was a lot of talk about this in the halls after the session, so it appears that there is definitely a desire to learn more about XML Schema Design Patterns:

[Kirk Allen Evans' Blog]
12:56:44 PM    trackback []     Articulate [] 

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.

[WebLogs @ ASP.NET]
9:15:11 AM    trackback []     Articulate [] 

Cool DataGrid Trick.

Did you know that you can trick the DataGrid's ButtonColumn to use an image for a button without having to use a TemplateColumn? It's actually really easy. In the DataGrid Property Builder, change the column's Button Type to “LinkButton”, then use regular HTML for the “Text” property, like so:

<IMG src="/common/images/icons/16/delete.gif" border=0>

Click “Apply“, and presto! you now have an image button without the hassle of having a TemplateColumn. Switch over to the ASPX code view, and you should see the following:

<asp:ButtonColumn Text="&lt;img src=&quot;/common/images/icons/16/delete.gif&quot; border=&quot;0&quot; /&gt;" CommandName="Delete" />

Nifty, huh?

[WebLogs @ ASP.NET]
9:08:23 AM    trackback []     Articulate []