Click here to Skip to main content
15,867,488 members
Articles / Web Development / IIS
Article

DataGrid's ViewState optimization

Rate me:
Please Sign up or sign in to vote.
4.59/5 (26 votes)
11 Apr 20055 min read 165.8K   1K   59   22
How to reduce DataGrid's ViewState size, while maintaining all DataGrid's functionalities.

Introduction

This article shows you how to reduce size of ViewState data generated by DataGrid control, while maintaining all DataGrid's functionality like selecting items or paging.

I assume that you know what it's and how to use ViewState. If not, please first learn about them, e.g. read article Taking a Bite Out of ASP.NET ViewState. In that article you also find general information about reducing size of ViewState.

Background

When I started to learn and use ASP.NET in practice, one of my problems was ViewState - usually it's too large! Usually I can reduce its size, by disabling it for selected controls or for whole page. Unfortunately, when I disable VS for control, sometime I lost some of its functionality. This is true for DataGrid - when you disable ViewState, you'll lose advanced functions like selecting items or paging. On the other side, ViewState generated by DataGrid is usually very large - it grows with every added row and column.

In last two weeks I decided to finally solve this problem. I assumed that DataGrid store copy of my DataTable in ViewState, or my data is stored column-by-column by BoundColumn objects. As I found later, it was a wrong assumption.

First I displayed the whole tree of controls used to display my page. First surprise - DataGrid uses internally other controls to display is contents. Here is sample control tree for 2x2 DataGrid:

  • DataGrid
    • DataGridTable
      • DataGridItem
        • TableCell
        • TableCell
      • DataGridItem
        • TableCell
        • TableCell

DataGridTable is the class derived from System.Web.UI.WebControls.Table. DataGridItem objects represents rows, and TableCell represents cells of DataGrid.

Next I decompiled .NET binaries using Reflector [^] and I browsed code of DataGrid, BaseDataList (its base class), BoundColumn, and DataGridColumn classes. Unfortunately I found nothing that may help me solve my problem.

In this point, I decided to try to decode and analyze contents of my ViewState. I used ViewState Decoder [^] for this. When I displayed my ViewState's data, its structure looked familiar for me. After wards, I found that - it's similar to control tree on my page! And I think - what if I disable ViewState for each row of DataGrid? I checked this and... Eureka! That's it!

How to reduce size of DataGrid's ViewState - summary

Disable ViewState

If you can, disable the ViewState for whole DataGrid (set property EnableViewState to false), or better for whole page. If you need advanced DataGrid's functionality like selecting items or paging, you can't use this method. In this case you should use methods listed below.

Disable columns autogeneration

Set property AutoGenerateColumns to false, and create columns manually using Property Builder for DataGrid control. When columns are generated automatically, information about them is stored in the ViewState.

Disable ViewState for each DataGrid's row

This is the best method, because copy of displayed data is stored in ViewState as values of TableCell.Text property. When you disable that, DataGrid ViewState's size will be constant and don't increase when you display more rows. You can use the following code for this:

C#
private void DisableViewState(DataGrid dg)
{
    foreach (DataGridItem dgi in dg.Items)
    {
        dgi.EnableViewState = false;
    }
}

private void Page_Load(object sender, System.EventArgs e)
{
    MyDataGrid.DataSource = GetData();
    MyDataGrid.DataBind();
    DisableViewState(MyDataGrid);
}

Store required identifiers in ViewState as string[] array

When you display data for user, you need to store identifiers of displayed data. You can store them in hidden DataGrid's column, but this is not optimal - your ids will be stored as DataGridItem/TableCell/string tree (you also need to change code from previous method to disable ViewState only for selected columns). Better solution is to store ids in ViewState as string[] array. Note: int[] array may seem to be more appropriate, but not: data generated by LosFormatter class is more compact for string[] array than for int[] array. This is caused by fact that class LosFormatter is optimized only for string[] arrays.

Example: You have array of three ids: 1, 2, 3. If you store them in ViewState as string[], you get:

@<1;2;3;>

When you store them as int[], you get:

@System.Int32, mscorlib, Version=1.0.5000.0, Culture=neutral, 
                  PublicKeyToken=b77a5c561934e089<i<1>;i<2>;i<3>;>

If you store more int[] arrays in ViewState, all except first will be stored as following:

@50<i<1>;i<2>;i<3>;>

Alternatively you can store your ids in ArrayList - below are data generated from ArrayList for values stored as string, and as int:

l<1;2;3;>
l<i<1>;i<2>;i<3>;>

Here is an example code that creates and stores array with ids in ViewState:

C#
DataTable dt = GetData();
MyDataGrid.DataSource = dt;
MyDataGrid.DataBind();

string[] ids = new string[dt.Rows.Count];
for (int n=0; n<dt.Rows.Count; ++n)
    ids[n] = dt.Rows[n]["id"].ToString();
ViewState["ids"] = ids;

When you need to retrieve id of displayed data, use following code:

C#
int index = MyDataGrid.SelectedIndex;
string[] ids = (string[])ViewState["ids"];
int myID = Convert.ToInt32(ids[index]);

Statistics

I created page that display a 10*10 table. Each cell contains a three digit number. Below are results of my tests:

VS - ViewState, CA - columns autogeneration.

DescriptionViewState size
VS enabled, CA enabled6032
VS enabled, CA disabled5028
VS disabled for rows, CA disabled236
VS disabled for cells in all column except first, CA disabled948
VS disabled for rows, CA disabled, ids stored in VS as int[]476
VS disabled for rows, CA disabled, ids stored in VS as string[]316
VS disabled for rows, CA disabled, ids stored in VS as ints in ArrayList356
VS disabled for rows, CA disabled, ids stored in VS as strings in ArrayList316

As you see ViewState, size is reduced from 6032 to 316 bytes. We saved 5716 bytes, and now ViewState contains only 5.2% of the beginning data!

Points of Interest

I worked on primary method covered in this article (disable ViewState for each DataGrid's row) for almost two weeks. It's true that simplest solutions are most difficult to find.

I found also that, data stored in ViewState could be optimized. This can be done if you know how LosFormatter works. Other method is to implement own class to replace LosFormatter and this is the subject for other article.

History

  • 4/11/2005

    First version.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Web Developer
Germany Germany
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
GeneralMy vote of 5 Pin
Daniel Cohen Gindi5-Mar-13 8:30
Daniel Cohen Gindi5-Mar-13 8:30 
GeneralWhat will be happen the if we write the code in ItemDataBound event of that grid Pin
Rounak Hasan5-Jun-11 21:21
Rounak Hasan5-Jun-11 21:21 
Questionhurrrry..,data in "GridView" invisible in post back,need the proper code for "viewstate" implementation Pin
sumans432428-Oct-09 21:43
sumans432428-Oct-09 21:43 
GeneralWhats the use of this when my data is lost on a post back Pin
bhat12343-Feb-06 23:56
bhat12343-Feb-06 23:56 
GeneralRe: Whats the use of this when my data is lost on a post back Pin
froman11815-Feb-06 7:52
froman11815-Feb-06 7:52 
GeneralTry to put 2 or more DataGrids with paging enabled! Pin
cupo11-Oct-05 12:01
cupo11-Oct-05 12:01 
GeneralRe: Try to put 2 or more DataGrids with paging enabled! Pin
Daniel Fruzynski12-Oct-05 7:38
Daniel Fruzynski12-Oct-05 7:38 
This is normal behaviour because DataGrids don't store copy of displayed data in its DataView. You must re-DataBind() grids after every postback:
C#
private void ShowGrid1(int nPage)
{
  DataGrid1.CurrentPageIndex = nPage;
  DataGrid1.DataSource = GetData1();
  DataGrid1.DataBind();
  DisableViewState(DataGrid1);
}

private void ShowGrid2(int nPage)
{
  DataGrid2.CurrentPageIndex = nPage;
  DataGrid2.DataSource = GetData2();
  DataGrid2.DataBind();
  DisableViewState(DataGrid2);
}

private void DataGrid1_PageIndexChanged(object source, System.Web.UI.WebControls.DataGridPageChangedEventArgs e)
{
  ShowGrid1(e.NewPageIndex);
  ShowGrid2(DataGrid2.CurrentPageIndex);
}

private void DataGrid2_PageIndexChanged(object source, System.Web.UI.WebControls.DataGridPageChangedEventArgs e)
{
  ShowGrid1(DataGrid1.CurrentPageIndex);
  ShowGrid2(e.NewPageIndex);
}

GeneralRe: Try to put 2 or more DataGrids with paging enabled! Pin
cupo12-Oct-05 12:31
cupo12-Oct-05 12:31 
GeneralRe: Try to put 2 or more DataGrids with paging enabled! Pin
Daniel Fruzynski13-Oct-05 7:34
Daniel Fruzynski13-Oct-05 7:34 
GeneralRe: Try to put 2 or more DataGrids with paging enabled! Pin
cupo13-Oct-05 13:16
cupo13-Oct-05 13:16 
GeneralRe: Try to put 2 or more DataGrids with paging enabled! Pin
Daniel Fruzynski14-Oct-05 22:17
Daniel Fruzynski14-Oct-05 22:17 
GeneralViewstate Optimization Pin
barani_7624-Jul-05 6:11
barani_7624-Jul-05 6:11 
GeneralGreat one! Pin
Abi Bellamkonda20-Apr-05 21:51
Abi Bellamkonda20-Apr-05 21:51 
GeneralI love an unintentional Pun! Pin
Anonymous21-Apr-05 4:13
Anonymous21-Apr-05 4:13 
GeneralRe: I love an unintentional Pun! Pin
Abi Bellamkonda21-Apr-05 13:25
Abi Bellamkonda21-Apr-05 13:25 
GeneralRe: I love an unintentional Pun! Pin
Xagyg3-Jun-08 4:40
Xagyg3-Jun-08 4:40 
GeneralRe: Great one! Pin
Bugsbuddy21-Apr-05 21:56
Bugsbuddy21-Apr-05 21:56 
GeneralRe: Great one! Pin
Abi Bellamkonda23-Apr-05 12:34
Abi Bellamkonda23-Apr-05 12:34 
QuestionHow different is this approach? Pin
Sathish Kumar K11-Apr-05 17:13
Sathish Kumar K11-Apr-05 17:13 
AnswerRe: How different is this approach? Pin
User 134930911-Apr-05 18:26
User 134930911-Apr-05 18:26 
GeneralRe: How different is this approach? Pin
Sathish Kumar K13-Apr-05 6:19
Sathish Kumar K13-Apr-05 6:19 
GeneralRe: How different is this approach? Pin
spvarapu29-Sep-05 21:38
spvarapu29-Sep-05 21:38 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.