I have a gridview on my page that gets bound to user search results. There can be many pages upto say 1000. Each page shows 50 records. I have the built in paging turned on for the grid. I want to disable the viewstate on the grid but then I have to bind the results on every page load. (bind twice on paging). The search takes a few seconds and I would not want to store the results in the session. So, how do I achieve turning off the viewstate for the grid or is it okay to have it enabled?
This must be a very common scenario. I hope there is a standard way of doing this.
Depending on how you bind the grid view you should implement server side paging so that your only bringing back the data from the server you need to display for one page.
What data access are you using i.e. are you using linq to sql?
Heres an article on how to do it with ObjectDataSource Custom paging and sorting
Avoid where ever possible putting large amounts of info into view state as it will bloat your page and effect performance.
Related
ASP.net webforms here, if I set AllowPaging=true and implement my own paging mechanism where I am fetching say 25 records at a time. I'd like to be able to use the default gridview pager, but it seems to be having trouble setting the number of pages. Is this an internal calculation where the ENTIRE dataset has to be binded for it to determine this calculation?
For instance, assume a query has 1000 rows and I want to only fetch 25 of them at a time. Does the gridview pager need to execute the 1000 rows as its datasource in order to get the correct number of pages (buttons) to display. I cant find a property allowing me to specify the number of pages, they all seem to be read only (get methods).
I want to avoid building my own pager...
The Effective Paging with GridView Control in ASP.NET Article describes how to implement the pagination where your gridview requests the data only for the page that is visible.
Don't be put off by the fact that the database query is executed twice. Once for the total count and another to get the page's data. For applications with high traffic or a lot of data, this approach is still more efficient than getting everything, loading into a gridview (and the view state!), sending it to the end user, and the browser loading it on the screen :).
That's where virtual paging comes in.
Set AllowCustomPaging to true.
In PageIndexChanging event, set VirtualItemCount and PageIndex to the proper value.
Put only the 25 rows in the DataSource, do a DataBind as usual, you're done.
I have a webpage in asp.net which uses editable grid to update/insert employee's records. A particular employee can have almost 50-70 attributes. Considering the frequent use of this page, I need to be very careful about the round trips to server and other I/O operations, as it might degrade the performance of page.
I am using a jquery plugin to choose from the given available columns. The left panel of listbox is populated using an xml file, which is read on server. The attributes are of multiple datatypes, such as simple string, integer or date.
The problem comes with the attributes which contain dropdown values, such as department, teams etc. Should I load the values of the dropdown values as the page loads in the start, irrespective of whether the user wishes to select the dropdowns or not? Or should I make another round trip to server and load the dropdown values of the selected attributes. Which approach should be used and why?
Note: There might be atmost 4 to 6 dropdown attributes, with maximum 30 to 40 values..
It really depends on both the odds of the user needing that dropdownlist, and how badly you'll want to avoid additional Ajax loads.
This is a very specific issue. But if your dropdownlist items won't really change on a per-item basis, I'd go with loading them during pageload. Else, if one employee's dropdownlist won't be the same as the other's, use Ajax so you can get a custom dropdownlist every time.
But like I said, very specific for your particular situation.
I am creating a custom control extending WebControl. This web control allows the consumer to define a collection of columns in markup, something like this:
<Custom:CustomGrid>
<Columns>
<Custom:DataColumn HeaderText="FirstName" />
<Custom:DataColumn HeaderText="LastName" />
</Columns>
and put an IEnumerable in a DataSource property and this is rendered out to a table.
This control also allows paging. The IEnumerable in DataSource is the full list, and I display a page of the list at a time. I am already saving the current page, number of rows per page, etc. to viewstate. Should I also put the full list in viewstate? Maybe session?
This list can become a bit hefty. Maybe save in session with a random key, which is saved in viewstate?
What is the best practice here?
Edit: I don't think it's right to impose that all types in the IEnumerable be serializable. Is that fair? So do I need to copy the data source to some other data structure for serialization?
Edit 2: Even if I do use a base control instead of implementing RenderChildControls I will need to implement CreateChildControls, but I will still need to persist the data somewhere, or did I miss the point of the base class?
Indeed, not all IEnumerable instances will be serializable.
If the query is cheap to run I wouldn't persist the whole data set but just run the query again for a different page or a change in the sort order.
If you put the data in viewstate you'll end up with huge pages. Session state might be acceptable if you don't have many users, but large data sets with lots of users won't scale well. What if I bind a million rows to your control? Or what if your control was used in a repeater and shown 100 times on a page?
Are you sure you need to persist the data? This isn't premature optimisation is it?
Remember that your control is a UI component. The viewstate should hold enough information to maintain the UI state as it is. A change in state (e.g.: switching to a different page of results) is something for which your control should pass responsibility to the data source.
Take a look at good old GridView. It displays what you give it and remembers that. If you're using paging then it raises an event to say "the user has changed page; give me page x of data". For me, that's the best practice for a UI control.
For implementing databound control it is better to use base class which was designed to perform such task. For example in ASP.NET exist CompositeDataboundControl which can be used as a base class to implement custom data bound controls. I can advice to review the following Dino Esposito article:
http://msdn.microsoft.com/en-us/library/aa479016.aspx.
Basically if you create control like ASP.NET gridview then it is store values in viewstate. To be more clear it is create number of the DataRow controls which saved assigned values in viewstate. During postback it recreates the same number of rows and values are restored from viewstate. If you will save only datasource for example in session without using viewstate then you will need to redatabind data to your grid during every postback. So, if you create Server control similar to gridview then approach described in the Dino Esposito post will be very helpful because it shows how to create control similar to ASP.NET Server GridView control.
I've a grid view, with IList as a datasource. I've thousands of records and so I've used pagination. The grid view will display only 10 records per page. My question is, how to avoid the grid view making DB calls again to the server when I click the 2nd page. Since I load all the data in a collection(IList), I need to iterate within the IList to bind data to the grid view when the next page is clicked. How can I accomplish this ? Help appreciated.
As you mentioned you have thousands of records I prefer you stay on database calls, you can reduce response time by bringing data in chunks like if you are showing 10 rows in grid view only bring 10 rows from the database. You can write a stored procedure where you can specify page size, start position, search criteria as parameters and change as per your need.
If you don't want to hit the database between postbacks during pagination, you need to store the list in memory somehow, perhaps using the Session property of the page, and then bind to that list. If the list can grow large (you mention thousands of records) I would recommend you to consider going via the database anyway, since that will preserve server memory.
In a Sharepoint web part, I have a DataGrid with paging that I load with all of the data (not using custom paging - custom paging would require a significant overhaul in the current process and is probably one of the last options I can try). I was wondering if it was possible to have it page through the data without re-binding the data source to the grid in the page index changed event? If I remove my current calls to re-bind the data, it remains on the first page no matter what.
With a datagrid, I think you need to re-bind the grid whenever you want to go to a new page.
"A typical handler for the PageIndexChanged event sets the CurrentPageIndex property to the index of the page you want to display and then uses the DataBind method to bind the data to the DataGrid control."
http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.datagrid.onpageindexchanged(VS.71).aspx
If you want to avoid querying/fetching the data over again from the source, then you'll need to "cache" the data between postbacks. There are various options here, each with it's own advantages and drawbacks.
If the size of the data is not too large and is not sensitive, you can simply put the data in viewstate on the first page load, and read it out again when the page index is changed. Another option might include using Session to "cache" the data, although this can get tricky if not done right, and of course there will be more load on the server side with this method (with varying amounts, depending on if the Session is In-Proc, State Server, or Database). There may be other methods to "cache" the data, but that is what you'd need to do in this case.