Why Must Data Binding Happen After Control Events?

418 words.

Okay, I know why. But just pretend like it could be different for the sake of this rant. Let’s say you have a GridView using a SqlDataSource on an ASP.NET page. Each row displays some data from a table. No problem.

Now let’s say you want to put a RadioButtonList in the first column of the grid. You want to update the underlying row when the user clicks one or the other radio buttons. You do NOT want to use the standard ASP.NET patterns for updating data because they suck and this is a slightly special case. You want to put a “Y” in a column if they click one of the radio buttons, and an “N” in the column if they click the other radio button. And you probably want to put it inside an UpdatePanel so it looks all AJAX-y.

This particular situation – handling controls inside GridViews – has baffled me since my first days of ASP.NET.

So you make a TemplateField for the column and put a RadioButtonList in it. Maybe you can bind it to the data easily, or maybe you have to setup a DataRowBound event to populate the control. Then you wire up your little SelectedIndexChanged event for the RadioButtonList. In the event handler, you cast the sender to a RadioButtonList. You look at the NamingContainer to find the GridViewRow containing the RadioButtonList. Then you pop up Intellisense and see GridViewRow.DataItem will give you the DataRowView for the underlying data so you can get the row’s ID and update the database.

Wrong.

Because, at runtime, GridViewRow.DataItem is null. What-the-eff?

Well, it’s because control events are fired long before data binding occurs. So at the time the SelectedIndexChanged fires, you have no idea what the underlying data for that row is. The only thing you know is the DataItemIndex.

Okay, no problem, surely I can stuff an ID or GUID for the row somewhere in the RadioButtonList that can be passed down to the SelectedIndexChanged event handler. Nope. You can’t do that. All you’ve got is that damnable DataItemIndex.

I have struggled for years to find an elegant solution for this, but I always end up in the same place: After fruitlessly searching for the perfect solution that must be out there but I just haven’t found yet, I give up and cache an array of database IDs on the Session during data binding so I can use it in the subsequent postback’s control event. It works, but it annoys me greatly.

Related

This page is a static archival copy of what was originally a WordPress post. It was converted from HTML to Markdown format before being built by Hugo. There may be formatting problems that I haven't addressed yet. There may be problems with missing or mangled images that I haven't fixed yet. There may have been comments on the original post, which I have archived, but I haven't quite worked out how to show them on the new site.

Sorry, new comments are disabled on older posts. This helps reduce spam. Active commenting almost always occurs within a day or two of new posts.