By default, the ViewState for ASP.NET DataGrids can be quite large, as it normally stores enough information to recreate the grid completely after a postback. Often, I have found that I need the grid to display a list of items with only paging, sorting, and some buttons that let you delete or edit (via another page) individual items. For this, there is no need for the page to survive a post-back and recreate itself, since each postback either reloads the grid's data or it jumps to another page.
Unfortunately, just disabling ViewState completely for the DataGrid results in no events being handled in ASP.NET, since the DataGrid is not recreated on a postback. This eliminates the obvious method of minimizing the ViewState since it doesn't allow for any of the things I need to do.
I had read another option suggesting that for each ItemCreated, you could set the individual DataGridItem's ViewState to False, and this indeed allows for paging and sorting to work -- but button events will not fire and we lose things like each item's ItemIndex. So, again, no dice.
Other ideas are to not use bound columns at all but rather to use template columns consisting of databound literals or labels with ViewState explicitly disabled, but I really like the simple, elegant and short code of bound columns, so I tried to see if there is any other way to go about this.
Well, after much fiddling around, here's the simple technique that seemed to work well:
private void DataGrid1_ItemCreated(object sender, DataGridItemEventArgs e)
foreach (TableCell c in e.Item.Cells)
The above code, which should be attached to the ItemCreated event, simply enumerates the TableCells for that item and disables their ViewStates. All other ViewStates for the DataGrid (individual DataGridItems and the DataGrid itself) still should have ViewState enabeld. This lets paging and sorting happen as normal, but now your button's events will fire and you will have access to the ItemIndex and DataKeys other useful features of the DataGridItem. This results in a much smaller ViewState since none of the text that is displayed in each cell is stored. The ViewState is still there and not totally eliminated, of course, but this seems to be a decent solution that keeps it as small as possible while not sacrificing too many features.
Remember, of course, that using this technique will mean that your DataGrid will not be fully restored on a postback! It's pretty cool, though, to see what happens -- the whole thing is re-created will all buttons and the correct number of rows and columns, just all of them are blank! Which is exactly what we want -- just the structure of the DataGrid itself to be preserved, not the actual data.
Note that it appears that databound CommandArgs on buttons will not persist when you use this technique, but to work around that you can just get the corresponding ID from the DataKeys collection of the DataGrid. Of course, you could also just disable the ViewState for only certain TableCells, not just all of them, if you like.