Al
45 Answers, 1 is accepted
protected void ObjectDataSource1_Selecting(object sender, ObjectDataSourceSelectingEventArgs e)
{
e.Arguments.MaximumRows = radGrid.MasterTableView.PageSize;
} I'm not sure why the grid can't figure this out by itself, but this seems to work okay. Unfortunately, after the grid applies the filter, my paging counts are not working. It appears that during filtering, the total record count is not being updated from the Object Data Source SelectCountMethod. Shouldn't this work exactly the same with or without filtering?
Al
Go through the following demo link.
http://www.telerik.com/DEMOS/ASPNET/Prometheus/Grid/Examples/Programming/CustomPaging/DefaultCS.aspx
Shinu.
My guess is, while in filter mode, the grid is calculating the record count based on the number of items in the grid and not getting it from the ObjectDataSource SelectCountMethod. This results in the Pager Item not providing the correct counts.
Please advise.
Thanks,
Al
Are you still investigating this issue?
I haven't been able to solve the problem. It sure seems like the Pager Item isn't picking up the total record count from the SelectCountMethod. The ObjectDataSource is getting the correct number from my business object, but it isn't finding its way back during filtering like it does durning normal paging and sorting.
Al
Can you please try setting the CanRetrieveAllData property of RadGrid's MasterTableView to false? Please give it a try and see if it helps.
Sincerely yours,
Rosen
the Telerik team
Instantly find answers to your questions at the new Telerik Support Center
Indeed setting CanRetrieveAllData to false will bypass the internal logic of the RadGrid control to retrieve all data when filtering, sorting and grouping and therefore filtering will be applied only on the currently given data. In this case you should handle the logic for filtering, sorting and grouping. You can review the link suggested by Shinu on how to accomplish custom paging.
Sincerely yours,
Rosen
the Telerik team
Instantly find answers to your questions at the new Telerik Support Center
Let me reiterate a few points:
- My business object only returns 10 records at a time because I'm working with a really large table.
- My paging works perfect without filtering.
- My business object's Select Count Method returns the correct number of records that match the filter expression.
- The paging and filtering worked with my business object in the previous version.
The paging and filtering will work fine if I return the entire data set, but that is not what I want to do. When filtering, it is my belief that the grid is using the number of records returned in the current data set to base the pager counts on and ignores the value returned from the Select Count Method.
If you can't recognize this problem, can you show me how I can verify what values are being used to create the Pager Item? I would like to verify whether or not the value from the Select Count Method is being used in the Pager Item.
Thanks,
Al
When paging with a filter applied, the NeedDataSource technique calls the Select method with the Maximum Rows parameter set to 100,000 (a hard coded number). The ObjectDataSource technique calls the Select method with the Maximum Rows parameter set to 2147483647. In both cases, a List is returned with all 100,000 objects created by the business object. The grid then applies the filter to the 100,000 records and the Pager Item maintains the proper counts.
I know this is just a simulation of paging and filtering, but this technique would not be very efficient when working with large database tables. I'm using a technique where my business object only returns the necessary records to display one page of the grid at a time. I'm effectively applying the filter expression on the database instead of having the grid apply the filter to the entire dataset. Ironically, this is the same approach used by your business object in the example when it performs paging without filtering. Again, my paging works fine until I apply a filter.
I found you can simulate this issue by changing the following line in MyBusinessObject.cs:
while (i < Math.Min(_maxItems, startRowIndex + maximumRows))
towhile (i < Math.Min(_maxItems, startRowIndex + 10)
This will continue to work for paging only, but when a filter is applied, only 10 records will be provided to the grid which will result in the Pager Item not displaying because there isn't more than one page to display.
At this point, it looks like I need a way to tell the grid not to apply the filter when it gets the data source and to use the correct count as returned from my business object's Select Count method.
I hope this helps.
Al
As I stated in my previous message when setting the CanRetrieveAllData to false you will get only the items for the current page exactly the same as you would with MS' GridView control. Therefore you will need to use custom filtering, sorting etc. For example in your DAL and give the RadGrid control only the items for the current page.
As for the online demo example its purpose is to illustrate how to handle the RadGrid paging logic for custom logic not to demonstrate data retrieval techniques.
If you continue experiencing difficulties, please send us (attached to a formal ticket) a small working project and we will be happy to assist you in resolving the problems.
Best wishes,
Rosen
the Telerik team
Instantly find answers to your questions at the new Telerik Support Center
I appreciate your continued support.
I am giving the RadGrid only the items for the current page. This works great for paging and sorting. When filtering, I continue to give the RadGrid only the items for the current page, but the counts are not calculated correctly in the Pager Item so the RadGrid always thinks there is only one page and does not show the correct counts in the Pager Item.
I will have to build an example project and submit a formal ticket.
To any other readers of this thread, has anyone successfully implemented custom paging and filtering using an object data source that only returns the exact number of records to be displayed on one page of the grid?
I would appreciate any feedback.
Thanks,
Al
I was wondering if there was ever any resolution to this issue? I am having the exact same problem, and I am also unable to fix it.
In my case, the data is coming from an ObjectDataSource that does all of it's own logic for paging, filtering, and sorting, and returns only a single page of data requested by the client.
I have a GridView and a RadGrid on the same page to test this. The GridView works flawlessly, but the RadGrid doesn't.
As suggested, I set the CanRetrieveAllData property to false, and this did resolve the maximumRows parameter issue being set to 214748364. Now it correctly sets the value to the page size, like the GridView.
However, the pager now disappears. I thought perhaps it was an issue with the VirtualItemCount property not being set, so I've turned on both AllowPaging and AllowCustomPaging, I set the VirtualItemCount to the "true" number of records, at both the design level AND at the run-time level, but the pager still does not display.
Curious, I set the AlwaysVisible property of the PagerStyle property of the MasterTableView to "True", and sure enough, the pager returns, but now I can see that the reason it wasn't displaying before is that it thinks it has the total number of records... i.e. the VirtualItemCount is 100, and the PageSize is 10. The pager says "Showing records 1-10 of 10." A breakpoint proves that the VirtualItemCount still is 100, even though the pager thinks it is 10.
I am 99% convinced this is a bug on Telerik's part. I can't think of what other properties need to be set to correct this problem.
Can you send us small example via support ticket where we can reproduce this?
Greetings,
Vlad
the Telerik team
Check out Telerik Trainer, the state of the art learning tool for Telerik products.
Date: 6/16/2008 10:50:51 AM
Thank's for notifying us about this problem. We found this is a bug in the present version of the control. A fix will be available officially later this week with the Service Pack 2 of RadControls for ASP.NET AJAX suite.
We have updated your Telerik points for the bug report.
Sincerely yours,
Nikolay
the Telerik team
Unfortunately, it wasn't fixed. Here is their last response to me:
Date: 8/18/2008 9:14:32 AM
This is just to inform you that we will need more time to look into the issue and get back to you with more information.
Thank you for the patience and understanding and excuse us in advance for the delay.
Greetings,
Plamen
the Telerik team
Vlad@Telerik, I'm attaching the code to this message rather than via a support ticket, because I think Al O (and others) might find it helpful. Thanks for your quick response.
The issue appears to be caused by building the columns of the RadGrid manually, specifically setting the "Aggregate" property of a bound column to anything other than "GridAggregateFunction.None". Other values for the enumeration (I've tested Sum and Count) cause the pager to disappear. The reason for the pager disappearing is that the RadGrid somehow believes that the one page of data being returned to it is the complete set of records, regardless of what the total records are, or VirtualItemCount, etc.
In other words, if you have 100 records, and a page size of 20, and your custom pager class returns a single page of 20 records, the RadGrid thinks that's it, and so there's no need to display a pager. However, as soon as you set the bound column's "Aggregate" property back to "None", the pager comes back, since the RadGrid is now aware of all 100 records, even though a single page is being returned.
The following is the ASPX page and code-behind (with a simple custom pager class, minus sorting and filtering) which illustrates this. I've used the Northwind database (.mdb file) as the datasource:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="AggregateBug.aspx.cs" Inherits="Tests.Telerik.AggregateBug" %> |
<%@ Register Assembly="Telerik.Web.UI" Namespace="Telerik.Web.UI" TagPrefix="telerik" %> |
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> |
<html xmlns="http://www.w3.org/1999/xhtml"> |
<head runat="server"> |
<title></title> |
</head> |
<body> |
<form id="form1" runat="server"> |
<div> |
<asp:Label ID="Label1" runat="server" Text="Label"></asp:Label> |
<br /> |
<telerik:RadScriptManager ID="RadScriptManager1" runat="server"> |
</telerik:RadScriptManager> |
<br /> |
<telerik:RadGrid ID="RadGrid1" runat="server" AllowCustomPaging="True" AllowPaging="True" |
AutoGenerateColumns="False" DataSourceID="ObjectDataSource1" GridLines="None" |
GroupingEnabled="False" PageSize="5" Skin="Telerik"> |
<MasterTableView CanRetrieveAllData="False"> |
<RowIndicatorColumn> |
<HeaderStyle Width="20px"></HeaderStyle> |
</RowIndicatorColumn> |
<ExpandCollapseColumn> |
<HeaderStyle Width="20px"></HeaderStyle> |
</ExpandCollapseColumn> |
</MasterTableView> |
<FilterMenu Skin="Telerik" EnableTheming="True"> |
<CollapseAnimation Type="OutQuint" Duration="200"></CollapseAnimation> |
</FilterMenu> |
</telerik:RadGrid> |
<br /> |
<asp:ObjectDataSource ID="ObjectDataSource1" runat="server" EnablePaging="True" OldValuesParameterFormatString="original_{0}" |
SelectCountMethod="GetCount" SelectMethod="PagedData" StartRowIndexParameterName="startRowIndex" |
MaximumRowsParameterName="maximumRows" TypeName="Tests.Telerik.TablePager" OnSelecting="ObjectDataSource1_Selecting"> |
<SelectParameters> |
<asp:Parameter Name="dt" Type="Object" /> |
</SelectParameters> |
</asp:ObjectDataSource> |
</div> |
</form> |
</body> |
</html> |
using System; |
using System.Data; |
using System.Data.OleDb; |
using System.Web; |
using System.Web.UI; |
using System.Web.UI.WebControls; |
using Telerik.Web.UI; |
namespace Tests.Telerik |
{ |
public partial class AggregateBug : System.Web.UI.Page |
{ |
protected void Page_Load(object sender, EventArgs e) |
{ |
if (!Page.IsPostBack) |
{ |
try |
{ |
BuildGrid1(); |
HttpRuntime.Cache.Remove("TableDetails"); |
OleDbConnection conn = new OleDbConnection(); |
conn.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\\Program Files\\Microsoft Office\\OFFICE11\\SAMPLES\\Northwind.mdb;User Id=admin;Password=;"; |
OleDbDataAdapter da = new OleDbDataAdapter("Select * from Products", conn); |
DataTable dt = new DataTable(); |
da.Fill(dt); |
Label1.Text = "Data retrieved."; |
Session["table"] = dt; |
} |
catch (Exception ex) |
{ |
Label1.Text = ex.Message; |
} |
} |
} |
protected void BuildGrid1() |
{ |
GridNumericColumn col1 = new GridNumericColumn(); |
RadGrid1.MasterTableView.Columns.Add(col1); |
col1.HeaderText = "Product ID"; |
col1.UniqueName = "ProductID"; |
col1.DataField = "ProductID"; |
col1.Reorderable = true; |
col1.ConvertEmptyStringToNull = true; |
col1.Aggregate = GridAggregateFunction.None; |
col1.AllowFiltering = true; |
col1.Groupable = true; |
col1.AllowSorting = true; |
GridBoundColumn col2 = new GridBoundColumn(); |
RadGrid1.MasterTableView.Columns.Add(col2); |
col2.HeaderText = "Product Name"; |
col2.UniqueName = "ProductName"; |
col2.DataField = "ProductName"; |
col2.Reorderable = true; |
col2.ConvertEmptyStringToNull = true; |
col2.Aggregate = GridAggregateFunction.None; |
col2.AllowFiltering = true; |
col2.Groupable = true; |
col2.AllowSorting = true; |
GridNumericColumn col3 = new GridNumericColumn(); |
RadGrid1.MasterTableView.Columns.Add(col3); |
col3.HeaderText = "Supplier ID"; |
col3.UniqueName = "SupplierID"; |
col3.DataField = "SupplierID"; |
col3.Reorderable = true; |
col3.ConvertEmptyStringToNull = true; |
col3.Aggregate = GridAggregateFunction.None; |
col3.AllowFiltering = true; |
col3.Groupable = true; |
col3.AllowSorting = true; |
GridBoundColumn col4 = new GridBoundColumn(); |
RadGrid1.MasterTableView.Columns.Add(col4); |
col4.HeaderText = "Qty/Unit"; |
col4.UniqueName = "QuantityPerUnit"; |
col4.DataField = "QuantityPerUnit"; |
col4.Reorderable = true; |
col4.ConvertEmptyStringToNull = true; |
col4.Aggregate = GridAggregateFunction.None; |
col4.AllowFiltering = true; |
col4.Groupable = true; |
col4.AllowSorting = true; |
GridNumericColumn col5 = new GridNumericColumn(); |
RadGrid1.MasterTableView.Columns.Add(col5); |
col5.HeaderText = "Unit Price"; |
col5.UniqueName = "UnitPrice"; |
col5.DataField = "UnitPrice"; |
col5.Reorderable = true; |
col5.ConvertEmptyStringToNull = true; |
col5.Aggregate = GridAggregateFunction.None; |
col5.AllowFiltering = true; |
col5.Groupable = true; |
col5.AllowSorting = true; |
} |
protected void ObjectDataSource1_Selecting(object sender, ObjectDataSourceSelectingEventArgs e) |
{ |
e.InputParameters["dt"] = (DataTable)Session["table"]; |
} |
} |
[System.ComponentModel.DataObject] |
public class TablePager |
{ |
private Int32 _detailCount; |
private Int32 DetailCount |
{ |
get { return _detailCount; } |
set { _detailCount = value; } |
} |
[System.ComponentModel.DataObjectMethodAttribute |
(System.ComponentModel.DataObjectMethodType.Select, true)] |
public DataTable PagedData(DataTable dt, int startRowIndex, int maximumRows) |
{ |
DataView dv = dt.DefaultView; |
DataTable dtPaged = dt.Clone(); |
Int32 finalRowOnPage = startRowIndex + maximumRows; |
for (int i = startRowIndex; i < (finalRowOnPage < dv.Count ? finalRowOnPage : dv.Count); i++) |
{ |
if (i < dv.Count) |
{ |
dtPaged.ImportRow(dv[i].Row); |
} |
} |
_detailCount = dv.Count; |
return dtPaged; |
} |
public Int32 GetCount(DataTable dt) |
{ |
return this.DetailCount; |
} |
} |
} |
In this initial example, notice that the "CanRetrieveAllData" property of the MasterTableView is "False" and all of the Aggregate properties for the bound columns in the BuildGrid1 method are set to "None", so everything works.
If you set one of the columns (e.g. UnitPrice) to have an Aggregate value of "Sum", you will immediately see the pager disappear, and if you set the RadGrid's "PagerStyle.AlwaysVisible" property to "True", you will see that the pager displays, but is inactive because again, it thinks that it has the entire set of records in that one page.
You can put a breakpoint in the GetDetailCount method of the custom TablePager class to verify that it is always returning the correct number of records via the ObjectDataSource's SelectCount method, but the RadGrid seems to ignore this when the Aggregate property of a bound column is anything other than "None".
Vlad@Telerik, hopefully I have explained this well enough and you're able to reproduce the bug.
Al O, perhaps the problem you are experiencing is caused by the same thing? Like you, I was also seeing the 2147483647 value for the maximumRows property until I set the "CanRetrieveAllData" value to "False". This is when I ran into the other problem.
In the meantime, I have just turned aggregates off for my grid, but it certainly would be nice to have them back, AND have custom paging working.
Thank you the sample page. We are able to reproduce this unwanted behavior and will do our best to provide a fix in the coming release of the RadControls for ASP.NET AJAX suite. Meanwhile I have updated your telerik points.
Please excuse us for the inconvenience.
Best wishes,
Rosen
the Telerik team
Check out Telerik Trainer, the state of the art learning tool for Telerik products.
Indeed the issue which Golem described has been addressed with current official release of RadControls for ASP.NET AJAX (2008.3.1125). Upgrade to this version following the instructions from here and let us know whether everything is OK.
Best regards,
Rosen
the Telerik team
Check out Telerik Trainer, the state of the art learning tool for Telerik products.
I upgraded to the new release and ran some tests. I found some different behavior, but it still doesn't work as expected.
First of all, let me reiterate that paging and sorting work perfectly. When I apply a filter, the new behavior is that I actually get the correct number of pages displayed in the pager on the first page displayed after the filter is applied.
Here is the pager text:
Displaying page 1 of 3, items 1 to 10 of 21.
Initially, this appears to be an improvement, but when I go to page two, I get the following text:
Displaying page 2 of 2, items 11 to 11 of 11.
The page is actually the last page and skips the second page.
If I go back to the first page, and then go to the third page, I get the following text:
Displaying page 1 of 1, items 1 to 1 of 1.
At this point, I have lost any ability to go back to page one or two.
I have also noticed that the performance is very bad like the grid is processing more than it should.
I have the following line of code in the ObjectDataSouce Selecting method:
e.Arguments.MaximumRows = grdOddDaysRequest.MasterTableView.VirtualItemCount; |
When I remove this, the paging performs real fast again, but of course my filtering doesn't work at all.
I hope this information is helpful as I would really like to finally get this resolved.
Al
I have attached a modified version of a page you have send previously which tries to achieve the behavior you are requested. Please take a look and let us know is this helps of if I'm missing something obvious.
Best wishes,
Rosen
the Telerik team
Check out Telerik Trainer, the state of the art learning tool for Telerik products.
Thanks,
Al
I am having the same problem as Al was having originally.
I have a RadGrid with a CslaDataSource. (It inherits from System.Web.UI.DataSourceControl just like ObjectDataSource.) I am doing my paging, sorting and filtering all at the database level.
Whenever a filter is applied the System.Web.UI.DataSourceSelectArguments.MaximumRows property that is passed to the datasource is 2147483647. And likewise the System.Web.UI.DataSourceSelectArguments.StartRowIndex property is set to 0. I would love it if the grid was able to produce accurate arguments in this scenario regardless of if filtering is applied or not.
The datasource that I am using does not have a Selecting event that I can subscribe to in order to implement the workaround described here as it applies to the ObjectDataSource.
Are there any plans to fix this bug? Thanks so much for working so hard on this issue.
--BH
Thanks for the reply.
When I set CanRetrieveAllData="false" that does set the System.Web.UI.DataSourceSelectArguments.MaximumRows to the correct value before retrieving the data. Unfortunately that creates a worse problem. Then after retrieving the data the grid disregards the TotalPageCount value that is passed back from the datasource. The grid's PageCount value is set to one reguardless. I get one page of results with no way to know how many other pages there are, or any way to get to them. This is not a viable workaround, unfortunately.
In addition, I am not using the built in sorting, paging, filtering, or grouping. I send the paging, sorting and filtering statements to my datalayer and return one page of results at a time. Seperately, each of these features is working great and I am very happy with them.
The whole reason that I am paging at the database level is that I can have up to 50,000 records returned. Loading all of these records into the grid takes a long time and can cause an out of memory exception. Returning one page of records at a time is much faster. However, the user can filter by a column and still have over 40,000 records returned. This query also needs to be paged. In this circumstance, it would be great if the grid could pass the correct arguments for filtering and paging, all at the same time.
Barnabas
I extended the RadGrid into a UserControl and added a couple of properties to manage all of this for me, and the properties bind to the labels every time the grid is databound. Effectively, like you, we're only ever binding to a single page of the grid, but we "fake out" the grid to think there are more pages, more records, etc., but the database is doing all of the work.
Thanks so much for your feedback. I am already using a PagerTemplate like this one to workaround the bug that I have documented in this post. Did you just extend this pager template? Would you mind posting some of the code that you have, or pointing me to a good example elsewhere? Thanks so much.
But this is still a workaround. It doesn't resolve the underlying issue that is still functioning incorrectly. If it weren't for these bugs, I could just use the built in pagers and life would be a lot easier.
Rosen,
Has this been logged as a bug? Is it just a lower priority right now because there is workaround that functions for most users?
Thanks for your time,
Barnabas
Can you please send us a small runnable project which demonstrates your problematic scenario? This way we will be able to add more context to the described behavior and if possible address it or provide a suitable workaround for your case.
All the best,
Rosen
the Telerik team
Instantly find answers to your questions on the new Telerik Support Portal.
Watch a video on how to optimize your support resource searches and check out more tips on the blogs.
So - I initially had similar problems working with filtering the grid when bound to an ObjectDataSource...
Everything seemed to work great re: paging & sorting when I didn't attempt to filter records.
But when I attempted to do any kind of filtering, the Grid kept requesting that all possible rows be retrieved. (ie: StartRowIndex = 0, MaxRows = int.MaxValue)
Then I discovered the "CanRetrieveAllData" setting, and thought - perfect! That's just what I need. I set it to false, and the filtering now properly sent in the appropriate values for StartRowIndex and MaxRows....
However, the grid's paging then seems to be broken - ie: it the grid seems to think there are only 10 rows of data available (assuming a page size of 10) when in fact there is a lot more. And my "GetCount" method was being called, and was returning the correct number of rows...It just seemed like the grid was ignoring it.
So, finally, I stumbled upon this post and mimicked your settings in your provided sample (thank you for creating that). Using your sample code as a template ended up correcting my problem...But in all honesty, this seems like a hack. It seems a bit outlandish that I would have to wipe the Grid's filter expression during selection and then restore it in pre-render...Sounds like there is still some ugly bug sitting under the covers...
It would be great if the underlying issue can be corrected, and this kludgy code wouldn't have to sit in all my web pages that need to support these features...
Or am I off base with this comment?
Roy
Actually handling in this way filtering is kind of a hack , as it is not an intended use of RadGrid. The proper way of manually handling (skipping the build-in logic) the filtering is to handle the ItemCommand event and to build the expression yourself and filtering the data, not to try to "trick" the control to build the expressions and then somehow to bypass the inner filtering.
Regards,
Rosen
the Telerik team
Instantly find answers to your questions on the new Telerik Support Portal.
Watch a video on how to optimize your support resource searches and check out more tips on the blogs.
We are also experencing the same issue stated by AI.We do the Custom Sorting,Paging and Filtering.
When we do the filter the maximumrows was set to 2147483647.So we added the canRetreiveAllData to false and the maximum rows was actually getting the correct value.But the problem with the pager still persists.The TotalRowCount is not been recognised eventhough we set the correct value.
Our filtered recordset has a total of 20 rows with 10 rows per page..So ideally it should have 10 records in apage and another 10 records in the second page..But it displays only one page with 10 records.
We are manually building the filter expresion from Item command and passing the filtesr to DAL to fetch from the database.
We are using the latest Telerik Software version 2010.1.519.40
But whe we use NeeddataSource event insetad of ObjectContainer-Selecting event the VirtualItem Count is getting set properly and we don't encounter this issue.
Yuor help on this is greatly appreciated
Thanks
Saru
This is very strange as I'm using this approach too and it does work for me. Maybe you can show us some of your code?
--BH
Actually We use ObjectContainerDataSource.Pls find below our Code behind Logic which performs Custom Sorting/Filtering/Paging
protected
void CategoryGrid_Selecting(object source, ObjectContainerDataSourceSelectingEventArgs e)
{
if (objContGridCategories.DataObjectTypeName.Trim().Length > 0)
{
//This will return the Total Record Count of filtered Data
int totalRowCount = _presenter.GetCategoriesCount(FilterCriteriaCollection);
//This will fetch the filtered data and assign to Radgrid
objContGridCategories.DataSource = _presenter.GetCategories(e.Arguments.StartRowIndex, e.Arguments.MaximumRows, e.Arguments.SortExpression, FilterCriteriaCollection);
objContGridCategories.TotalRowCount = totalRowCount;
}
}
Iam setting the canRetrieveAlldata to false
Assume we have 20 records matching the filter criteria and the Page Size is 10.ideally we should get 2 pages of data.But it dislpays only the first page.This is not the case with NeeddataSource the VirtualItem Count is getting set properly.
Thanks
Saru
You can apply the same technique as shown in the sample I have attached previously. For your convenience I have attached a sample page (View) which demonstrates a simple integration with ObjectContainerDataSource and WCSF.
Regards,
Rosen
the Telerik team
Thanks for your answer and it works fine.Since we are storing the FilerExpression in ViewState we don't have to use the PreRender Logic too I guess.
Why is that this issue is not happening when we use NeedDataSourecEvent.I guess it would be better to use the NeedDataSource Event insetad of ObjectConatiner.Beacuse our DAL actaully returns the object which can be directly set to the RadGrid Datsource in NeedDataSourceEvent.
Thanks
Saru
There is a difference of how populating through a DataSourceControl and NeedDataSource is handled internally as provided "information" in this cases is a bit different, depending on the DataSourceControl type and supported capabilities.
Greetings,
Rosen
the Telerik team
Thank you for the example. That got my RadGrid working with my ObjectDataSource. I have just 3 problems. I am using virtual scroll paging and ajax. When I set a filter, everything is fine. But when I scroll to a new page, the filter visually disappears but still works and sends the correct data to my ObjectDataSource. So, it's a visual issue only. But it looks to the user as if we have removed their filter.
The second problem is once a filter has been applied, there is no way to remove the filter. Selecting "No Filter" doesn't work.
The third problem is that on every ajax postback, the ObjectDataSource's SelectMethod is getting called twice. First with the input parameters from the previous ajax postback, then again with the new input parameters. The problem with this is that it is making 2 expensive queries to the database and throwing the first one's results away. I need it to just call the database once per ajax postback.
Below is a sample page which shows the problems. For the first problem, apply a filter, then scroll to a new page, and you will see the filter disappears but the data is obviously still filtered. for the second problem, just apply a filter then try to remove the filter with "No Filter" and you will see the data is still filtered. The third issue can be seen by placing a break point in the Select() method of the CustomData.cs file, then load the page, then scroll to a new page, the break point will get hit twice.
Thank you,
Jason
Default.aspx
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<
html
xmlns
=
"http://www.w3.org/1999/xhtml"
>
<
head
runat
=
"server"
>
<
title
></
title
>
<
style
type
=
"text/css"
>
#RadAjaxLoadingPanel1RadGrid1
{
background-color: rgba(0,0,0,0.5) !important;
}
</
style
>
</
head
>
<
body
>
<
form
id
=
"form1"
runat
=
"server"
>
<
telerik:RadScriptManager
ID
=
"RadScriptManager1"
runat
=
"server"
>
</
telerik:RadScriptManager
>
<
telerik:RadAjaxManager
ID
=
"RadAjaxManager1"
runat
=
"server"
>
<
AjaxSettings
>
<
telerik:AjaxSetting
AjaxControlID
=
"RadGrid1"
>
<
UpdatedControls
>
<
telerik:AjaxUpdatedControl
ControlID
=
"RadGrid1"
LoadingPanelID
=
"RadAjaxLoadingPanel1"
>
</
telerik:AjaxUpdatedControl
>
</
UpdatedControls
>
</
telerik:AjaxSetting
>
</
AjaxSettings
>
</
telerik:RadAjaxManager
>
<
telerik:RadAjaxLoadingPanel
ID
=
"RadAjaxLoadingPanel1"
runat
=
"server"
>
</
telerik:RadAjaxLoadingPanel
>
<
telerik:RadGrid
ID
=
"RadGrid1"
runat
=
"server"
DataSourceID
=
"ObjectDataSource1"
AutoGenerateColumns
=
"false"
EnableViewState
=
"false"
EnableLinqExpressions
=
"false"
AllowSorting
=
"true"
AllowPaging
=
"true"
AllowCustomPaging
=
"true"
PageSize
=
"14"
AllowFilteringByColumn
=
"true"
OnPreRender
=
"RadGrid1_PreRender"
>
<
PagerStyle
AlwaysVisible
=
"true"
></
PagerStyle
>
<
MasterTableView
EnableColumnsViewState
=
"false"
CanRetrieveAllData
=
"false"
>
</
MasterTableView
>
<
ClientSettings
>
<
Scrolling
AllowScroll
=
"true"
EnableVirtualScrollPaging
=
"true"
UseStaticHeaders
=
"true"
SaveScrollPosition
=
"true"
>
</
Scrolling
>
</
ClientSettings
>
</
telerik:RadGrid
>
<
asp:ObjectDataSource
ID
=
"ObjectDataSource1"
runat
=
"server"
TypeName
=
"CustomData"
SelectMethod
=
"Select"
SelectCountMethod
=
"SelectCount"
EnablePaging
=
"true"
OnSelecting
=
"ObjectDataSource1_Selecting"
>
<
SelectParameters
>
<
asp:ControlParameter
Name
=
"typeID"
ControlID
=
"TypeID"
PropertyName
=
"Value"
/>
<
asp:Parameter
Name
=
"startRowIndex"
Type
=
"Int32"
/>
<
asp:Parameter
Name
=
"maximumRows"
Type
=
"Int32"
/>
<
asp:Parameter
Name
=
"filterExpression"
Type
=
"String"
/>
<
asp:Parameter
Name
=
"sortExpression"
Type
=
"String"
/>
<
asp:Parameter
Direction
=
"Output"
Name
=
"rowCount"
Type
=
"Int32"
/>
</
SelectParameters
>
</
asp:ObjectDataSource
>
<
asp:HiddenField
ID
=
"TypeID"
runat
=
"server"
/>
</
form
>
</
body
>
</
html
>
Default.aspx.cs
using
System;
using
System.Web.UI.WebControls;
using
Telerik.Web.UI;
public
partial
class
Default : System.Web.UI.Page
{
private
string
_filterExpression =
string
.Empty;
protected
void
Page_Init(
object
sender, EventArgs e)
{
// query string variable "TypeID" is passed to database
var typeID = Request.QueryString[
"TypeID"
];
if
(!IsPostBack)
{
TypeID.Value = typeID;
}
// generate columns dynamically based on TypeID
var numberCol =
new
GridBoundColumn();
numberCol.DataField =
"Number"
;
numberCol.HeaderText =
"Number"
;
numberCol.SortExpression =
"[Number]"
;
numberCol.DataType =
typeof
(
int
);
RadGrid1.Columns.Add(numberCol);
var dateCol =
new
GridBoundColumn();
dateCol.DataField =
"Date"
;
dateCol.HeaderText =
"Date"
;
dateCol.SortExpression =
"[Date]"
;
dateCol.DataType =
typeof
(DateTime);
dateCol.DataFormatString =
"{0:MMMM d, yyyy}"
;
RadGrid1.Columns.Add(dateCol);
}
protected
void
ObjectDataSource1_Selecting(
object
sender, ObjectDataSourceSelectingEventArgs e)
{
if
(!
string
.IsNullOrEmpty(RadGrid1.MasterTableView.FilterExpression))
{
_filterExpression = RadGrid1.MasterTableView.FilterExpression;
RadGrid1.MasterTableView.FilterExpression =
string
.Empty;
}
e.InputParameters[
"filterExpression"
] = _filterExpression;
e.InputParameters[
"sortExpression"
] = RadGrid1.MasterTableView.SortExpressions.GetSortString();
}
protected
void
RadGrid1_PreRender(
object
sender, EventArgs e)
{
RadGrid1.MasterTableView.FilterExpression = _filterExpression;
}
}
CustomData.cs
using
System;
using
System.Data;
public
class
CustomData
{
private
int
_count;
public
CustomData()
{
// constructor
}
public
int
SelectCount(
string
typeID,
int
startRowIndex,
int
maximumRows,
string
filterExpression,
string
sortExpression,
out
int
rowCount)
{
// allinput parameters are ignored in this method but needed because they are specified in the SelectParameters and needed for the SelectMethod
// _count is set in the Select method call
rowCount = _count;
return
_count;
}
public
DataTable Select(
string
typeID,
int
startRowIndex,
int
maximumRows,
string
filterExpression,
string
sortExpression,
out
int
rowCount)
{
// typeID is passed to the database as part of the query
// create sample data
var dataTable =
new
DataTable();
dataTable.Columns.Add(
new
DataColumn(
"Number"
,
typeof
(
int
)));
dataTable.Columns.Add(
new
DataColumn(
"Date"
,
typeof
(DateTime)));
var dateCol = DateTime.Parse(
"12/31/2010"
);
for
(var i = 1; i <= 40000; i++)
{
dataTable.Rows.Add(
new
object
[] { i, dateCol });
// decrement for next row
dateCol = dateCol.AddDays(-1);
}
// filter and sort sample data
var outputRows = dataTable.Select(filterExpression, sortExpression);
// populate count for SelectCount method call
_count = outputRows.Length;
rowCount = _count;
// create datatable with just 1 page of data to return
var outputTable =
new
DataTable();
outputTable.Columns.Add(
new
DataColumn(
"Number"
,
typeof
(
int
)));
outputTable.Columns.Add(
new
DataColumn(
"Date"
,
typeof
(DateTime)));
var endIndex = startRowIndex + maximumRows;
if
(endIndex >= outputRows.Length)
endIndex = outputRows.Length;
for
(var i = startRowIndex; i < endIndex; i++)
{
outputTable.Rows.Add(outputRows[i].ItemArray);
}
return
outputTable;
}
}
All problems have been reproduced. We will get back as soon as we have some result on your issue.
All the best, Tsvetoslav
the Telerik team
Default.aspx
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="Default" %>
<!DOCTYPE html>
<
html
xmlns
=
"http://www.w3.org/1999/xhtml"
>
<
head
runat
=
"server"
>
<
title
></
title
>
</
head
>
<
body
>
<
form
id
=
"form1"
runat
=
"server"
>
<
div
>
<
telerik:RadScriptManager
ID
=
"RadScriptManager1"
runat
=
"server"
>
</
telerik:RadScriptManager
>
<
telerik:RadAjaxManager
ID
=
"RadAjaxManager1"
runat
=
"server"
>
<
AjaxSettings
>
<
telerik:AjaxSetting
AjaxControlID
=
"RadGrid1"
>
<
UpdatedControls
>
<
telerik:AjaxUpdatedControl
ControlID
=
"RadGrid1"
LoadingPanelID
=
"RadAjaxLoadingPanel1"
>
</
telerik:AjaxUpdatedControl
>
</
UpdatedControls
>
</
telerik:AjaxSetting
>
</
AjaxSettings
>
</
telerik:RadAjaxManager
>
<
telerik:RadAjaxLoadingPanel
ID
=
"RadAjaxLoadingPanel1"
runat
=
"server"
>
</
telerik:RadAjaxLoadingPanel
>
<
telerik:RadGrid
ID
=
"RadGrid1"
runat
=
"server"
DataSourceID
=
"ObjectDataSource1"
OnItemCommand
=
"RadGrid1_ItemCommand"
AutoGenerateColumns
=
"false"
EnableLinqExpressions
=
"false"
AllowSorting
=
"true"
AllowPaging
=
"true"
AllowCustomPaging
=
"true"
PageSize
=
"14"
AllowFilteringByColumn
=
"true"
>
<
PagerStyle
AlwaysVisible
=
"true"
></
PagerStyle
>
<
MasterTableView
EnableColumnsViewState
=
"false"
CanRetrieveAllData
=
"false"
>
<
Columns
>
</
Columns
>
</
MasterTableView
>
<
ClientSettings
>
<
Scrolling
AllowScroll
=
"true"
EnableVirtualScrollPaging
=
"true"
UseStaticHeaders
=
"true"
SaveScrollPosition
=
"true"
></
Scrolling
>
</
ClientSettings
>
</
telerik:RadGrid
>
<
asp:ObjectDataSource
ID
=
"ObjectDataSource1"
runat
=
"server"
TypeName
=
"CustomData"
SelectMethod
=
"Select"
SelectCountMethod
=
"SelectCount"
EnablePaging
=
"true"
OnSelecting
=
"ObjectDataSource1_Selecting"
>
<
SelectParameters
>
<
asp:ControlParameter
Name
=
"typeID"
ControlID
=
"TypeID"
PropertyName
=
"Value"
/>
<
asp:Parameter
Name
=
"startRowIndex"
Type
=
"Int32"
/>
<
asp:Parameter
Name
=
"maximumRows"
Type
=
"Int32"
/>
<
asp:Parameter
Name
=
"filterExpression"
Type
=
"String"
/>
<
asp:Parameter
Name
=
"sortExpression"
Type
=
"String"
/>
<
asp:Parameter
Direction
=
"Output"
Name
=
"rowCount"
Type
=
"Int32"
/>
</
SelectParameters
>
</
asp:ObjectDataSource
>
<
asp:HiddenField
ID
=
"TypeID"
runat
=
"server"
/>
</
div
>
</
form
>
</
body
>
</
html
>
Posted on Feb 10, 2013 (permalink)
Hello Rosen,Thank you for the example. That got my RadGrid working with my ObjectDataSource. I have just 3 problems. I am using virtual scroll paging and ajax. When I set a filter, everything is fine. But when I scroll to a new page, the filter visually disappears but still works and sends the correct data to my ObjectDataSource. So, it's a visual issue only. But it looks to the user as if we have removed their filter.
The second problem is once a filter has been applied, there is no way to remove the filter. Selecting "No Filter" doesn't work.
The third problem is that on every ajax postback, the ObjectDataSource's SelectMethod is getting called twice. First with the input parameters from the previous ajax postback, then again with the new input parameters. The problem with this is that it is making 2 expensive queries to the database and throwing the first one's results away. I need it to just call the database once per ajax postback.
Below is a sample page which shows the problems. For the first problem, apply a filter, then scroll to a new page, and you will see the filter disappears but the data is obviously still filtered. for the second problem, just apply a filter then try to remove the filter with "No Filter" and you will see the data is still filtered. The third issue can be seen by placing a break point in the Select() method of the CustomData.cs file, then load the page, then scroll to a new page, the break point will get hit twice.
Thank you,
Jason
Default.aspx
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<
html
xmlns
=
"http://www.w3.org/1999/xhtml"
>
<
head
runat
=
"server"
>
<
title
></
title
>
<
style
type
=
"text/css"
>
#RadAjaxLoadingPanel1RadGrid1
{
background-color: rgba(0,0,0,0.5) !important;
}
</
style
>
</
head
>
<
body
>
<
form
id
=
"form1"
runat
=
"server"
>
<
telerik:RadScriptManager
ID
=
"RadScriptManager1"
runat
=
"server"
>
</
telerik:RadScriptManager
>
<
telerik:RadAjaxManager
ID
=
"RadAjaxManager1"
runat
=
"server"
>
<
AjaxSettings
>
<
telerik:AjaxSetting
AjaxControlID
=
"RadGrid1"
>
<
UpdatedControls
>
<
telerik:AjaxUpdatedControl
ControlID
=
"RadGrid1"
LoadingPanelID
=
"RadAjaxLoadingPanel1"
>
</
telerik:AjaxUpdatedControl
>
</
UpdatedControls
>
</
telerik:AjaxSetting
>
</
AjaxSettings
>
</
telerik:RadAjaxManager
>
<
telerik:RadAjaxLoadingPanel
ID
=
"RadAjaxLoadingPanel1"
runat
=
"server"
>
</
telerik:RadAjaxLoadingPanel
>
<
telerik:RadGrid
ID
=
"RadGrid1"
runat
=
"server"
DataSourceID
=
"ObjectDataSource1"
AutoGenerateColumns
=
"false"
EnableViewState
=
"false"
EnableLinqExpressions
=
"false"
AllowSorting
=
"true"
AllowPaging
=
"true"
AllowCustomPaging
=
"true"
PageSize
=
"14"
AllowFilteringByColumn
=
"true"
OnPreRender
=
"RadGrid1_PreRender"
>
<
PagerStyle
AlwaysVisible
=
"true"
></
PagerStyle
>
<
MasterTableView
EnableColumnsViewState
=
"false"
CanRetrieveAllData
=
"false"
>
</
MasterTableView
>
<
ClientSettings
>
<
Scrolling
AllowScroll
=
"true"
EnableVirtualScrollPaging
=
"true"
UseStaticHeaders
=
"true"
SaveScrollPosition
=
"true"
>
</
Scrolling
>
</
ClientSettings
>
</
telerik:RadGrid
>
<
asp:ObjectDataSource
ID
=
"ObjectDataSource1"
runat
=
"server"
TypeName
=
"CustomData"
SelectMethod
=
"Select"
SelectCountMethod
=
"SelectCount"
EnablePaging
=
"true"
OnSelecting
=
"ObjectDataSource1_Selecting"
>
<
SelectParameters
>
<
asp:ControlParameter
Name
=
"typeID"
ControlID
=
"TypeID"
PropertyName
=
"Value"
/>
<
asp:Parameter
Name
=
"startRowIndex"
Type
=
"Int32"
/>
<
asp:Parameter
Name
=
"maximumRows"
Type
=
"Int32"
/>
<
asp:Parameter
Name
=
"filterExpression"
Type
=
"String"
/>
<
asp:Parameter
Name
=
"sortExpression"
Type
=
"String"
/>
<
asp:Parameter
Direction
=
"Output"
Name
=
"rowCount"
Type
=
"Int32"
/>
</
SelectParameters
>
</
asp:ObjectDataSource
>
<
asp:HiddenField
ID
=
"TypeID"
runat
=
"server"
/>
</
form
>
</
body
>
</
html
>
Default.aspx.cs
using
System;
using
System.Collections.Generic;
using
System.Data;
using
System.Linq;
using
System.Web;
using
System.Web.UI;
using
System.Web.UI.WebControls;
using
Telerik.Web.UI;
public
partial
class
Default : System.Web.UI.Page
{
protected
void
Page_Init(
object
sender, EventArgs e)
{
// query string variable "TypeID" is passed to database
var typeID = Request.QueryString[
"TypeID"
];
if
(!IsPostBack)
{
TypeID.Value = typeID;
}
// generate columns dynamically based on TypeID
var numberCol =
new
GridBoundColumn();
numberCol.DataField =
"Number"
;
numberCol.HeaderText =
"Number"
;
numberCol.SortExpression =
"[Number]"
;
numberCol.DataType =
typeof
(
int
);
RadGrid1.Columns.Add(numberCol);
var dateCol =
new
GridBoundColumn();
dateCol.DataField =
"Date"
;
dateCol.HeaderText =
"Date"
;
dateCol.SortExpression =
"[Date]"
;
dateCol.DataType =
typeof
(DateTime);
dateCol.DataFormatString =
"{0:MMMM d, yyyy}"
;
RadGrid1.Columns.Add(dateCol);
}
protected
void
ObjectDataSource1_Selecting(
object
sender, ObjectDataSourceSelectingEventArgs e)
{
if
(!e.ExecutingSelectCount)
{
foreach
(var pair
in
this
.ColumnFilterValues)
{
RadGrid1.MasterTableView.GetColumn(pair.Key).CurrentFilterFunction = (GridKnownFunction)Enum.Parse(
typeof
(GridKnownFunction), pair.Value.First.ToString());
RadGrid1.MasterTableView.GetColumn(pair.Key).CurrentFilterValue = pair.Value.Second.ToString();
}
e.InputParameters[
"filterExpression"
] = GetFilterExpression();
e.InputParameters[
"sortExpression"
] = RadGrid1.MasterTableView.SortExpressions.GetSortString();
RadGrid1.MasterTableView.FilterExpression =
string
.Empty;
}
}
private
string
GetFilterExpression()
{
string
filterExpression =
string
.Empty;
foreach
(GridColumn column
in
this
.RadGrid1.MasterTableView.RenderColumns)
{
if
(!column.SupportsFiltering())
{
continue
;
}
string
filterText = column.EvaluateFilterExpression();
if
(String.IsNullOrEmpty(filterText))
{
column.ResetCurrentFilterValue();
continue
;
}
if
(!String.IsNullOrEmpty(filterExpression))
{
filterExpression +=
" AND "
;
}
filterExpression +=
"("
+ filterText +
")"
;
}
return
filterExpression;
}
private
Dictionary<
string
, Pair> ColumnFilterValues
{
get
{
if
(
this
.ViewState[
"ColumnFilterValues"
] ==
null
)
{
this
.ViewState[
"ColumnFilterValues"
] =
new
Dictionary<
string
, Pair>();
}
return
(Dictionary<
string
, Pair>)
this
.ViewState[
"ColumnFilterValues"
];
}
set
{
this
.ViewState[
"ColumnFilterValues"
] = value;
}
}
protected
void
RadGrid1_ItemCommand(
object
sender, GridCommandEventArgs e)
{
if
(e.CommandName == RadGrid.FilterCommandName)
{
Pair pair = e.CommandArgument
as
Pair;
string
columnUniqueName = pair.Second.ToString();
if
(!ColumnFilterValues.ContainsKey(columnUniqueName))
{
ColumnFilterValues.Add(columnUniqueName,
null
);
}
ColumnFilterValues[columnUniqueName] =
new
Pair(pair.First, RadGrid1.MasterTableView.GetColumn(columnUniqueName).CurrentFilterValue);
}
}
}
CustomData.cs
using
System;
using
System.Data;
public
class
CustomData
{
private
int
_count;
public
CustomData()
{
// constructor
}
public
int
SelectCount(
string
typeID,
int
startRowIndex,
int
maximumRows,
string
filterExpression,
string
sortExpression,
out
int
rowCount)
{
// allinput parameters are ignored in this method but needed because they are specified in the SelectParameters and needed for the SelectMethod
// _count is set in the Select method call
rowCount = _count;
return
_count;
}
public
DataTable Select(
string
typeID,
int
startRowIndex,
int
maximumRows,
string
filterExpression,
string
sortExpression,
out
int
rowCount)
{
// typeID is passed to the database as part of the query
// create sample data
var dataTable =
new
DataTable();
dataTable.Columns.Add(
new
DataColumn(
"Number"
,
typeof
(
int
)));
dataTable.Columns.Add(
new
DataColumn(
"Date"
,
typeof
(DateTime)));
var dateCol = DateTime.Parse(
"12/31/2010"
);
for
(var i = 1; i <= 40000; i++)
{
dataTable.Rows.Add(
new
object
[] { i, dateCol });
// decrement for next row
dateCol = dateCol.AddDays(-1);
}
// filter and sort sample data
var outputRows = dataTable.Select(filterExpression, sortExpression);
// populate count for SelectCount method call
_count = outputRows.Length;
rowCount = _count;
// create datatable with just 1 page of data to return
var outputTable =
new
DataTable();
outputTable.Columns.Add(
new
DataColumn(
"Number"
,
typeof
(
int
)));
outputTable.Columns.Add(
new
DataColumn(
"Date"
,
typeof
(DateTime)));
var endIndex = startRowIndex + maximumRows;
if
(endIndex >= outputRows.Length)
endIndex = outputRows.Length;
for
(var i = startRowIndex; i < endIndex; i++)
{
outputTable.Rows.Add(outputRows[i].ItemArray);
}
return
outputTable;
}
}
We have the same problem and using the latest version. Was this ever resolved by telerik?
Sorting works, but not filtering. We are adding GridBoundColumn's from code behind and using ObjectDataSource if that could affect anything.
I am a bit confused about what you are asking.
You said you have "the same problem". Same as what problem? In 45 posts thread several different problems was discussed and resolved. The first post is before more than 5 years and the last one is before 3 our versions.
If you have any problem, please open new thread and describe your problem good details.
Regards,
Vasil
Telerik