DCSIMG
Using UpdatePanel to Disable GridView View State - Doron's .NET Space

Using UpdatePanel to Disable GridView View State

View state. We usually hate it and love it at the same time. It's definitely a creature of comfort: having our controls automatically maintaining state is definitely a useful thing. But it can also be quite hazardous to your page performance - especially when used with a GridView that has many rows. This big-ass hidden field that gets generated is sure to make your users' round-trips quite a pain. And so the million dollar question is...

How do I disable view state and stay alive?

When you go ahead and mark that GridView of yours with EnableViewState="false" you'll notice that you now have to bind to your DataGrid's DataSource on every post-back. Otherwise, how would it know what rows to render? You have to do it, since the entire page is rendered on each and every post-back. And so you need to get those rows back from the Database even though nothing has changed (sure, you can use caching to eliminate this cost, but caching is not always easy to achieve).

But, if you use an UpdatePanel correctly, you can re-render the grid only when it changes, and still leave the view state off. Let's see how we can achieve this. Here's our page markup and code behind:

<form id="form1" runat="server">

    <asp:TextBox ID="FirstName" runat="server"/>

    <asp:TextBox ID="LastName" runat="server"/>

    <asp:Button ID="AddPerson" runat="server" Text="Add" OnClick="AddPerson_Click" />

 

    <asp:GridView runat="server" ID="PeopleGrid">

    </asp:GridView>

  </form>

public partial class PeoplePage : System.Web.UI.Page

{

    private PeopleRepository _peopleRepository =  new PeopleRepository();

 

    protected void Page_Load(object sender, EventArgs e)

    {

       if (!Page.IsPostBack)

       {

           BindGrid();

       }

    }

 

    protected void AddPerson_Click(object sender, EventArgs e)

    {

        _peopleRepository.Add(new Person(FirstName.Text, LastName.Text));

        BindGrid();

    }

 

    private void BindGrid()

    {

        PeopleGrid.DataSource = _peopleRepository.GetAll();

        PeopleGrid.DataBind();

    }

}

All is nice and simple: we have a grid, and two text boxes that allow us to add a person to the grid. Note that we only access the data source once on the very first page-load, and whenever we add a new person. Not on every post-back.

Now, if we wanted to turn view-state off, we'd have to make a few changes. This is how our markup will now look like:

<form id="form1" runat="server">

  <asp:ScriptManager ID="ScriptManager1" runat="server" />

  <asp:UpdatePanel ChildrenAsTriggers="false" UpdateMode="Conditional" runat="server" ID="PeoplePanel">

    <ContentTemplate>

      <asp:TextBox ID="FirstName" runat="server"/>

      <asp:TextBox ID="LastName" runat="server"/>

      <asp:Button ID="AddPerson" runat="server" Text="Add" OnClick="AddPerson_Click" />

      <asp:GridView runat="server" ID="PeopleGrid" EnableViewState="false">

      </asp:GridView>

    </ContentTemplate>

  </asp:UpdatePanel>

</form>

There are a few things to note here. We've added an UpdatePanel, and we changed its UpdateMode to Conditional and its ChildrenAsTriggers property to false. I am doing this in order to manually control exactly when the UpdatePanel gets updated. Since, as you can see, I've turned off the view-state for the grid, I only want it to be updated after the grid was bound - In any other case the grid will be completely empty, since without view-state it can't automatically recover its state.

So when does the UpdatePanel get updated? When we tell it to. Let's change the BindGrid private method.

private void BindGrid()

{

    PeopleGrid.DataSource = _peopleRepository.GetAll();

    PeopleGrid.DataBind();

    PeoplePanel.Update();

}

Note how we manually update the panel whenever we update the grid. The rest of the code is left unchanged. By making sure the update panel is only updated when grid is re-bound, we'll always have rows in our grid, even though view-state is off. This method works beautifully when you have a page with several un-related GridViews. You can turn off view-state for them all, and only update what you need, when you need it.

So, to recap, if you want to turn off view-state for your grid, you need to follow these steps:

  1. Put an UpdatePanel around the grid, make sure you set UpdateMode to Conditional and its ChildrenAsTriggers property to false.
  2. Make sure you manually call the Update method of the UpdatePanel every time you bind the grid to the data, and only then.
  3. Set the EnableViewState property on your grid to false, and enjoy the improved performance!

This way, any post-back that you have on the page that doesn't change the grid will not upload a huge view-state field, and it won't require you hit the data-source again. Also, less data is sent back to the client.

Of course, if you have inline editing in your grid, this is not going to work very well for you, as you'll probably need the state for each row the user edits. The solution for that, is, well... Don't use inline editing. It's not good for you.

If you want to have a look at the entire example code, you can grab it right here.

Published Friday, May 23, 2008 8:07 PM by dorony
תגים:

Comments

# re: Using UpdatePanel to Disable GridView View State

This does not work if the columns are not autogenerated.

Wednesday, October 08, 2008 9:27 PM by Edward Meshuris

# re: Using UpdatePanel to Disable GridView View State

I've used this method without auto-generating columns. What was your problem?

Thursday, October 16, 2008 4:33 AM by dorony

# re: Using UpdatePanel to Disable GridView View State

i want to thaaaaaaaaaaaaaaaaaaaaank you

as much as i can because may be more than year i have been searching for that

thanks agin

Tuesday, April 07, 2009 2:21 AM by rayed

# re: Using UpdatePanel to Disable GridView View State

Do we really need an UpdatePanel for this, just set the EnableViewState="false"

it will do.

As the whole content is enclosed in the UpdatePanel, it is not doing any real good here.

With ir withour updatepanel, Data is being stored in the session, bound to gridview and is being transfered to client on every add.

So what is the point???

Thursday, July 16, 2009 11:30 PM by EnableViewState="false"

# re: Using UpdatePanel to Disable GridView View State

You need an update panel, if you have (and you probably do) other postbacks in the page that are not related to the grid.

Perhaps some other grid -  say Grid B (and we'll call the first one Grid A). If you do an operation on Grid B - that doesn't affect Grid A at all - and you don't have an update panel on Grid A (on which you turned view-state off), you will have to rebind Grid A for every postback in the page - even those that are caused by Grid B and do not affect A at all.

If you have an UpdatePanel on Grid A, it will stay unchanged, unless you explicitly update it.

Friday, July 17, 2009 1:19 PM by dorony

# re: Using UpdatePanel to Disable GridView View State

I got the following exception when I tried to do something similar in my own code:

Sys.WebForms.PageRequestManagerServerErrorException: System.ArgumentException: Invalid postback or callback argument. Event validation is enabled using <pages enableEventValidation="true"/> in configuration or <%@ Page EnableEventValidation="true" %> in a page. For security purposes, this feature verifies that arguments to postback or callback events originate from the server control that originally rendered them. If the data is valid and expected, use the ClientScriptManager.RegisterForEventValidation method in order to register the postback or callback data for validation.

at System.Web.UI.ClientScriptManager.ValidateEvent(String uniqueId, String argument)

at System.Web.UI.Control.ValidateEvent(String uniqueID, String eventArgument)

at System.Web.UI.WebControls.DropDownList.LoadPostData(String postDataKey, NameValueCollection postCollection)

at System.Web.UI.WebControls.DropDownList.System.Web.UI.IPostBackDataHandler.LoadPostData(String postDataKey, NameValueCollection postCollection)

at System.Web.UI.Page.ProcessPostData(NameValueCollection postData, Boolean fBeforeLoad)

at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)

Monday, October 19, 2009 10:50 AM by brian

# re: Using UpdatePanel to Disable GridView View State

I have a page simillar to what you have described in your article. In my case I have a link button inside my grid. Since I have set EnableViewstate="False" on the grid the RowCommand event is not firing.

Do you have work arround for this issue. Please advice.

Thanks,

Vijay.

Tuesday, April 27, 2010 3:12 PM by Vijay

Leave a Comment

(required) 
(required) 
(optional)
(required) 

Enter the numbers above: