This is a migrated thread and some comments may be shown as answers.

ViewState optimization

8 Answers 85 Views
Grid
This is a migrated thread and some comments may be shown as answers.
Martin Roussel
Top achievements
Rank 1
Martin Roussel asked on 12 Jul 2012, 05:54 PM
Hi everyone,

Sorry if such question has already been asked, but i cant find a topic that helps me completely.

First of all, Im using a RadGrid with most of the grid functions (Sorting, Paging, Grouping and Filtering). Im populating my grid with data coming from my database (as a ObservableCollection<Class>) through the page's code-behind, columns are auto-generated (nothing special so far). Note that my grid's EnableViewState="False".

The first problem i encountered was i had to use the OnNeedDataSource property (which i added), otherwise i was losing my grid data content when using the sorting and such. I then noticed that OnNeedDataSource was always requesting my database so I created a ViewState variable that will contain my collection variable in order to save those database round-trips (for each sorting, page change, etc.). The approach i chose was to only create a ViewState on the first grid function (ex: first time we do a sort). The reason is because most of my users wont do grid functions at all (so for those users, Viewstate wont be used at all). I accomplished this by adding some handlers (OnItemCommand, OnGroupsChanging) that create the ViewState if it doesnt exist already (OnNeedDataSource checks also for it).

Everything seemed to work as expected until i noticed that one grid function seemed to be failing at random occasion: playing with the expendable/foldable rows (when header(s) are grouped). The only way i could fix this was by adding the EnableViewState="True" to the grid, but now i end up with 2 ViewState per grid...which i dont really like.

My questions:
1-Is it normal that I depend on the EnableViewState="True" for expendable/foldable rows (where all other functions work with my "custom" Viewstate?)
2-Can that second "auto-generated" Viewstate (EnableViewState="True") be used to do the job of the first one? If yes, how can we access it?
3-Is there a way to force the OnItemCommand and OnGroupsChanging handlers to be fired before OnNeedDataSource? Having this would save me a round-trip.
4-Do you propose a better way to save the database round-trips?
5-I was wondering if it is a best practice to manually clear Viewstate variable that we create ourselves (when page quits/redirect)? If yes, any example?
6-Do you think letting the grid asking the database everytime would be less load on the server than 2 Viewstates?

Here are snippets of my code i have so far:
<telerik:RadGrid ID="RadGrid1" runat="server" PageSize="5" Width="75%"
                AllowSorting="True" AllowFilteringByColumn="True"  AllowMultiRowSelection="True" AllowPaging="True"
                ShowGroupPanel="True" GridLines="None" AutoGenerateColumns="True" ShowFooter="True"
                OnItemCommand="testcomm" OnGroupsChanging="testgroup" OnColumnsReorder="testreorder"
                OnNeedDataSource="RadGrid1_NeedDataSource" 
                Skin="WebBlue" EnableViewState="True" >
                
                    <PagerStyle Mode="NextPrevAndNumeric"></PagerStyle>
 
                    <ClientSettings AllowDragToGroup="True" AllowColumnsReorder="True" ReorderColumnsOnClient="True">
                        <Resizing AllowColumnResize="true" />
                    </ClientSettings>
 
                    <GroupingSettings ShowUnGroupButton="true" />
 
                </telerik:RadGrid

protected void RadGrid1_NeedDataSource(object source, Telerik.Web.UI.GridNeedDataSourceEventArgs e)
    {
        ObservableCollection<PersonDTO> col = new ObservableCollection<PersonDTO>();
 
 
        if (ViewState["RadGrid1_DataSource"] != null)
        {
            col = (ObservableCollection<PersonDTO>)ViewState["RadGrid1_DataSource"];
      
        }
        else
        {
 
            col = GridDataSource2();
 
        }
 
        RadGrid1.DataSource = col;
 
    }
 
 private void LoadViewState()
    {
        ObservableCollection<PersonDTO> col = new ObservableCollection<PersonDTO>();
 
        if (ViewState["RadGrid1_DataSource"] == null)
        {
 
            // collection isn't in view state, so we need to load it from scratch.
            if (RadGrid1.DataSource == null)
            {
                col = GridDataSource2();
            }
            else
            {
                col = (ObservableCollection<PersonDTO>)RadGrid1.DataSource;
            }
 
            if (col != null)
            {
 
                ViewState.Add("RadGrid1_DataSource", col);
 
            }
        }
    }
 
    protected void testcomm(object o, Telerik.Web.UI.GridCommandEventArgs e)
    {
        LoadViewState();
    }
 
    protected void testreorder(object o, Telerik.Web.UI.GridColumnsReorderEventArgs e)
    {
        LoadViewState();
    }
 
    protected void testgroup(object o, Telerik.Web.UI.GridGroupsChangingEventArgs e)
    {
        LoadViewState();
    }


Thanks...and sorry btw for the long post but i wanted to make everything clear.

8 Answers, 1 is accepted

Sort by
0
Andrey
Telerik team
answered on 17 Jul 2012, 12:01 PM
Hi,

Thank you for contacting us.

As this help topic says when you are using advanced features of RadGrid like paging, sorting, grouping and filtering you need to use either declarative datasource or NeedDataSource event.

Additionally, the same features require the EnableViewState property is set to True. This is mentioned in this help topic.

On the other hand you could not handle the ViewState manually because RadGrid stores many property values in ViewState that are not exposed as public member. Therefore you need handle the ViewState manually.

You could not change the life-cycle of the control, so you could not force RadGrid to fire ItemCommand and OnGroupsChanging events at different stage.

I hope this information helps. Let me know if I can assist you any further.

Kind regards,
Andrey
the Telerik team
If you want to get updates on new releases, tips and tricks and sneak peeks at our product labs directly from the developers working on the RadControls for ASP.NET AJAX, subscribe to their blog feed now.
0
Martin Roussel
Top achievements
Rank 1
answered on 17 Jul 2012, 12:20 PM
thanks for the reply. Can you please precise more this part, since it sounds contradictory:

"On the other hand you could NOT handle the ViewState manually because RadGrid stores many property values in ViewState that are not exposed as public member. Therefore you need handle the ViewState manually."

To sum it up, can you (or anyone) help answering the questions ive asked, i think some left unanswered:

My questions:
1-Is it normal that I depend on the EnableViewState="True" for expendable/foldable rows (where all other functions work with my "custom" Viewstate?) ->YES
2-Can that second "auto-generated" Viewstate (EnableViewState="True") be used to do the job of the first one? If yes, how can we access it from code-behind? ->?
3-Is there a way to force the OnItemCommand and OnGroupsChanging handlers to be fired before OnNeedDataSource? Having this would save me a round-trip. -> NO
4-Do you propose a better way to save the database round-trips? ->?
5-I was wondering if it is a best practice to manually clear Viewstate variable that we create ourselves (when page quits/redirect)? If yes, any example? ->?
6-Do you think letting the grid asking the database everytime would be less load on the server than 2 Viewstates? ->?

TIA
0
Andrey
Telerik team
answered on 18 Jul 2012, 01:29 PM
Hello,

Please, excuse me fore being unclear.

I meant "You should not handle ViewState manually."

I think we are not on the same wave length. When you are doing grouping you should enable the ViewState of RadGrid with the EnableViewState property set to True.

On the other hand you could store your data in a ViewState property but this property should no be filled conditionally. It should be filled before RadGrid needs the data for example in the PageLoad event. Once you have filled the data container and have the EnableViewState property set to true RadGrid will bind correctly and all the available functionality will work as expected.

I hope this answers your questions.

Regards,
Andrey
the Telerik team
If you want to get updates on new releases, tips and tricks and sneak peeks at our product labs directly from the developers working on the RadControls for ASP.NET AJAX, subscribe to their blog feed now.
0
Martin Roussel
Top achievements
Rank 1
answered on 18 Jul 2012, 02:07 PM
Andrey,

Sorry if im not clear, but it doesnt answer my question(s).

Im using EnableViewState =True and dont plan to change that. I assume, by declaring such thing, the control creates automatically a Viewstate (with an unknown ID??). I dont want neither to use my additional "custom" Viewstate to replace that Viewstate's job, but asking the inverse: Can I access (read) the auto-generated Viewstate (created with the EnableViewState =True) and use that one for my own other purposes (in this case, saving my database round-trip)? The question is basically, what could be the ID of that auto Viewstate? Maybe the answer is no, we cant access it, dont bother... but im asking.

Basically, what i want to achieve at the end of the day is eliminating completely my "custom" Viewstate and only use the auto-generated one (while having the database round-trip reduced).

TIA
0
Andrey
Telerik team
answered on 18 Jul 2012, 03:46 PM
Hi,

ASP.NET ViewState is a client-state persister based on key-value dictionary that is used to save the values of the properties of given control. Doing so you are preserving the client-state of the controls between the postbacks. This ViewState is different for every logged user.

Since the ViewState is a key-value dictionary the only "ID" that it has is the "ViewState". You are accessing the value of some property by providing the property name through indexers:

var datasource = ViewState["datasource"];

You could find more information about the ASP.NET ViewState in this MSDN thread.

All the best,
Andrey
the Telerik team
If you want to get updates on new releases, tips and tricks and sneak peeks at our product labs directly from the developers working on the RadControls for ASP.NET AJAX, subscribe to their blog feed now.
0
Mick
Top achievements
Rank 1
answered on 30 Jul 2015, 02:23 AM

Interesting thread.  A little disappointing though it seems this guy had no luck getting a resolution on this. Telerik radgrid on a page we're serving up is sucking up 90K of viewstate.  I don't quite understand why the only options are on or off for viewstate.  Surely there's an inbetween.... Like having viewstate options for each feature like 

EnableViewStateSortexpressions
EnableViewStateFilters

etc

etc

0
Mick
Top achievements
Rank 1
answered on 30 Jul 2015, 03:00 AM
Also the sample supplied here...

http://www.telerik.com/support/code-library/retain-expanded-selected-state-in-hierarchy-on-rebind

...is a nice starter, but inadequate , it should be expanded to include saving of Filters, Sorting, Pagindex etc.
0
Angel Petrov
Telerik team
answered on 03 Aug 2015, 12:51 PM
Hi,

Can you please elaborate on the exact functionality you are targeting? Maybe we can provide a possible solution for it.

As for persisting the grid state there is a built-in solution to the problem and that is using our persistence framework. A demo illustrating such functionality can be seen here.

Regards,
Angel Petrov
Telerik
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
Tags
Grid
Asked by
Martin Roussel
Top achievements
Rank 1
Answers by
Andrey
Telerik team
Martin Roussel
Top achievements
Rank 1
Mick
Top achievements
Rank 1
Angel Petrov
Telerik team
Share this question
or