Demystifying Infragistics WebGrid DataBinding

Think you know everything about how the grid databinds?  Just starting to work with the grid and want to understand databinding?  Either way, read on.

DataBinding First Steps

In the basic scenario, you set the DataSourceID of the WebGrid at design-time, and your done.  Well, almost done.  There are a couple of additional properties that will be critical in making the grid's internals like sorting and paging work.  First, be sure to set the DataKeyField on the grid to the primary key field of your database table.  Next, I like to set the Band's BaseTableName property as well, don't actually know if this is necessary, but it's there so I set it.  This creates a link between a given band, and a Table in the datasource, which sounds like a good thing to me.  These properties can all be set at design-time or run-time.  Speaking of run-time..

DataBinding in Code

The first step - use the InitializeDataSource event of the grid!  Because the grid requires data at different points during the page lifecycle according to the features being used, there isn't one place where data can be bound.  Assigning data in the page_init may be too early in some cases, and page_load may be late in other cases.  Because of the strict requirements the grid has on when it needs data, the InitializeDataSource event is how the Grid will request data.  In this event, you must assign the grid's datasource (and be sure if it's a dataset, it has data in it).  You don't need to call DataBind, just setting the datasource is enough in this event.

And now for an apology....  If you used the WebGrid between 2006 and 2008, you likely noticed that the InitializeDataSource event had 'disappeared' from the CLR2.0 grid (in C# only).  At first this seemed like a good idea.. the datasources included in VisualStudio 2005 didn't require manually calling DataBind anymore, so the event wasn't needed, right?  Wrong!  I forgot about the key scenario of run-time databinding.  I gave the go-ahead to hide the event (we didn't remove it from the object model, we simply made it 'invisible').  We realize the oversight and finally took action to make the event public again.  Thank you to all of the customers who called us out on this and plead to get the event back.  If you go into Visual Studio 2005 or 2008 and notice that "InitializeDataSource" is missing form the Grid's event list, you can manually add the event handler.  This can be done declaratively through the WebGrid's ASPX (OnInitializeDataSource="myhandler") or through code in the OnInit method.  (grid.InitializeDataSource+=...)

[Note: A special thanks to Chris Lukose, the Infragistics Corporate Trainer for his work in lobbying for this event to be brought back again.]

2 Way DataBinding (Automatic Updating)

Did you know that the grid supports automatic data updating through the datasource control?  The days of complicated event handlers dealing with DataSets accepting and rejecting changes are over!!  Let's take a SqlDataSource for an example of how to use this feature. 

When you create the datasource be sure to click on the "advanced" when building the select statement.  You'll see a checkbox for "generate insert, update and delete".  Checking that box will enable the datasource to perform all of the 'crud' operations on your table.  The grid will automatically update the data, but first a 'postback' must occur.  I put a postback in quotes because it can be the traditional full page, or it can be an asynchronous AJAX style postback.  If you want the database to be updated with each row modification, you can add a server-side "RowUpdate" event handler.  Enabling the AJAX functionality of the grid (click the "Enable AJAX" checkbox in the smart tag at design-time, or set grid.DisplayLayout.LoadOnDemand=Xml) will make the updaterow happen asynchronously, making the entire update process transparent to the end user.  If you can't get updating working, check to be sure you set the grid's DataKeyField and BaseTableName properties (Yes, I'm speaking from experience).

UpdateRow VS UpdateRowBatch

When you take a look at the events for the Grid, you'll notice a few "Update" and "UpdateBatch" events.  What's the difference?  The Update events will fire as soon as the action occurs.  For instance, "UpdateRow" fires when you modify a value in a row and then focus leaves that row.  UpdateRowBatch however, will not fire until some mechanism cases the page to be posted back to the server (again, this can be a traditional or AJAX postback).  Using UpdateRowBatch means you can have a button which is used to update all changes once the user is done.  This is a very common usage scenario where the end user may be modifying multiple fields, but doesn't want to commit changes until they're sure it's right.  There is one oversight though.  The current implementation of UpdateRowBatch will fire the update events as soon as any postback occurs.  This could have been the result of any button click, or any other control.  This unfortunately means that you must commit the changes to something, even if the 'save' button was not clicked.  You can work around this by ensuring that nothing else will cause the page (or the grid) to postback in your application other than the 'save' button, but I'm sure there are going to be cases where that's not possible.  This is something that I'm currently lobbying to change in the Aikido version of the grid.

Manual Updating (Disconnected Data)

If the datasource you're using doesn't support automatic updates (business objects, datasets, lists) then you'll need to take the changes from the grid and persist them into your datamodel.  The easiest approach is to again use the UpdateRow or UpdateRowBatch events which will fire for each updated row, giving you an opportunity to persist the changes.  You can use the eventargs to find out the old values and new values, and decide to accept or reject the changes.  When manually updating your database, I'd recommend keeping your data in a keyed collection to make it easy to get a 'row' using a key value (primary key filed).  As an example, if you're binding to a collection of 'people', be sure that your collection is keyed on "personId".  You can make "personId" a hidden column in the grid, so that it doesn't show up in the display for the end user.  Additionally, if you make it hidden, be sure to make it 'serveronly' so that the data for that column never even has to be transmitted over the wire (why waste the bandwidth when you only need the data on the server..)

Advanced DataBinding

If you thought you knew everything about databinding in the grid, here's a hidden gem.  The EventArgs passed into the InitializeDataSource event can be upcast to "DataSourceEventArgs".  What does that mean?  It gives you fine grained functionality of how the grid retrieves data.  You can use this to implement partial databinding in the grid (feed the grid ONLY the rows needed for the current page, etc).  This is critical for achieving optimal performance in your application, since only you really know the details of your data implementation (Are you caching your data?  Is it quicker to retrieve all of the data at once and store it in a cache, or does it make more sense to fetch 'pages' of data at a time? ...)  As this is the case, you can use the InitializeDataSource event and the DataSourceEventArgs to feed the grid to match your data model.

2 Comments

  • Damn... Thank you, you helped me catch my stupid mistake. I was trying to figure out why I couldn't get 2-way databinding to work with my gridview and I completely forgot to set the DataKeyField.
    Thanks again!

  • I found that Updaterow and UpdateRowBatch interfer when you have cascading Combobox, which make a post back .

    Also the Cascading combo box posting back make no sense, as it could just call a AJAX web service using out of band call as in AJAX Toolkit.

    Look out for Cascading combobox Sample in AJAX tool Kit.
    Comparing that functionality with infragistics it makes infragistic looks like grid of 18th century.

    Wake Up look at what is available in the market before launching the product.

Comments have been disabled for this content.