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

FilterExpression is always out of date when rebinding

22 Answers 306 Views
Grid
This is a migrated thread and some comments may be shown as answers.
Craig
Top achievements
Rank 1
Craig asked on 18 Jul 2013, 08:17 AM
There is a stackoverflow question which hilights the exact issue im having problems with:
http://stackoverflow.com/questions/17486458/telerik-mastertableview-filterexpression-always-out-of-date#

Where I have a custom grid, and whenever I am doing a rebind I want to get the FilterExpression and pass it to my underlying linq queryable to add the filters to the existing query. However whenever I get the FilterExpression from the grid it is always displaying the previous filter state, not the most recent one.

If you read the scenarios in the stackoverflow post it hilights the exact scenarios in which this occurs, so is there any way round this issue, or to force the FilterExpression to be updated for use?

22 Answers, 1 is accepted

Sort by
0
Andrey
Telerik team
answered on 23 Jul 2013, 06:15 AM
Hello,

The behavior you are describing sounds as a databinding issue or there might be problem with instantiating and persisting the control. Could you share how you are using this custom Grid instance in your page. The full page source code along with the code-behind file could help the people willing to help you to better understand the case.

Regards,
Andrey
Telerik
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 the blog feed now.
0
Craig
Top achievements
Rank 1
answered on 23 Jul 2013, 08:00 AM
[ToolboxData("<{0}:LazyLoadedGrid runat=server></{0}:LazyLoadedGrid>")]
    public class LazyLoadedGrid : RadGrid
    {
        public string DefaultSortColumn
        {
            get { return ViewState["DefaultSortColumn"] as string ?? string.Empty; }
            set { ViewState["DefaultSortColumn"] = value; }
        }
 
        private string CurrentSortExpression
        {
            get { return ViewState["CurrentSortExpression"] as string ?? string.Empty; }
            set { ViewState["CurrentSortExpression"] = value; }
        }
 
        private string CurrentFilterExpression
        {
            get { return ViewState["CurrentFilterExpression"] as string ?? string.Empty; }
            set { ViewState["CurrentFilterExpression"] = value; }
        }
         
        public virtual bool EnableLazyFiltering
        {
            get
            {
                if (ViewState["EnableLazyFiltering"] == null)
                { return false; }
                return (bool)ViewState["EnableLazyFiltering"];
            }
            set
            {
                ViewState["EnableLazyFiltering"] = value;
                base.AllowFilteringByColumn = value;
                MasterTableView.AllowFilteringByColumn = value;
            }
        }
 
        public virtual bool EnableDynamicPageValues
        {
            get
            {
                if (ViewState["EnableDynamicPageValues"] == null)
                { return false; }
                return (bool)ViewState["EnableDynamicPageValues"];
            }
            set
            {
                ViewState["EnableDynamicPageValues"] = value;
            }
        }
 
        public virtual bool EnableLazyPaging
        {
            get
            {
                if (ViewState["EnableLazyPaging"] == null)
                { return false; }
                return (bool)ViewState["EnableLazyPaging"];
            }
            set
            {
                ViewState["EnableLazyPaging"] = value;
                base.AllowCustomPaging = value;
                MasterTableView.AllowCustomPaging = value;
                MasterTableView.AllowPaging = true;
                 
            }
        }
 
        public virtual bool EnableLazySorting
        {
            get
            {
                if (ViewState["EnableLazySorting"] == null)
                { return false; }
                return (bool)ViewState["EnableLazySorting"];
            }
            set
            {
                ViewState["EnableLazySorting"] = value;
                MasterTableView.AllowCustomSorting = value;
                MasterTableView.AllowSorting = true;
            }
        }
 
        public override object DataSource
        {
            get { return base.DataSource; }
            set
            {
                if (!(value is IQueryable) && value != null)
                { throw new LazyLoadingException("Lazy Loading Controls are *ONLY* compatible with IQueryable based datasources, please make sure you are using an expression tree not a result set for the DataSource"); }
 
                base.DataSource = value;
            }
        }
 
        public override bool AllowCustomPaging
        {
            get { return base.AllowCustomPaging; }
            set { EnableLazyPaging = value; }
        }
         
        public override GridTableView CreateTableView()
        { return new GridTableView(this); }
 
        protected override void OnDataBinding(EventArgs e)
        {
            if (DataSource != null)
            {
                OverrideDataSource(CurrentFilterExpression, CurrentSortExpression);
            }
             
            base.OnDataBinding(e);
        }
 
        protected override void OnItemCreated(GridItemEventArgs e)
        {
            if (e.Item is GridPagerItem)
            {
                if (EnableDynamicPageValues)
                {
                    var pagingComboBox = e.Item.FindControl("PageSizeComboBox") as RadComboBox;
                    CalculateDynamicPageSizes(VirtualItemCount, pagingComboBox);
                }
            }
            base.OnItemCreated(e);
        }
 
        protected override void OnPageIndexChanged(GridPageChangedEventArgs e)
        {
            CurrentPageIndex = e.NewPageIndex;
            Rebind();
            base.OnPageIndexChanged(e);
        }
 
        protected override void OnPageSizeChanged(GridPageSizeChangedEventArgs e)
        {
            PageSize = e.NewPageSize;
            Rebind();
            base.OnPageSizeChanged(e);
        }
 
        protected override void OnItemCommand(GridCommandEventArgs e)
        {
            if (e.CommandName == FilterCommandName)
            {
                CurrentFilterExpression = MasterTableView.FilterExpression;
                Rebind();
            }
             
            base.OnItemCommand(e);
        }
 
        protected override void OnSortCommand(GridSortCommandEventArgs e)
        {
            if (e.NewSortOrder == GridSortOrder.Ascending)
            { CurrentSortExpression = e.SortExpression; }
            else
            { CurrentSortExpression = string.Format("{0} descending", e.SortExpression); }
 
            Rebind();
            base.OnSortCommand(e);
        }
 
        protected virtual void CalculateDynamicPageSizes(int dataSourceCount, RadComboBox pageSizeDropdown)
        {
            var sizes = new Dictionary<string, string>();
 
            if (dataSourceCount > 10) { sizes.Add("10", "10"); }
            if (dataSourceCount > 20) { sizes.Add("20", "20"); }
            if (dataSourceCount > 50) { sizes.Add("50", "50"); }
            if (dataSourceCount > 100) { sizes.Add("100", "100"); }
            if (dataSourceCount > 500) { sizes.Add("500", "500"); }
            if (dataSourceCount > 1000) { sizes.Add("1000", "1000"); }
            if (dataSourceCount > 5000) { sizes.Add("5000", "5000"); }
            sizes.Add("All", dataSourceCount.ToString());
 
            pageSizeDropdown.Items.Clear();
            foreach (var size in sizes)
            {
                var newPageCountComboItem = new RadComboBoxItem() { Text = size.Key, Value = size.Value };
                newPageCountComboItem.Attributes.Add("ownerTableViewId", MasterTableView.ClientID);
                pageSizeDropdown.Items.Add(newPageCountComboItem);
            }
 
            var currentPageCountString = MasterTableView.PageSize >= dataSourceCount ? "All" : MasterTableView.PageSize.ToString();
 
            var selectedPageCount = pageSizeDropdown.FindItemByText(currentPageCountString);
            if (selectedPageCount != null)
            { selectedPageCount.Selected = true; }
        }
 
        protected virtual void OverrideDataSource(string filterExpression, string sortExpression)
        {
            var currentQuery = base.DataSource as IQueryable;
 
            if (EnableLazyFiltering)
            { currentQuery = AddFilteringLogicToQuery(currentQuery, filterExpression); }
 
            base.VirtualItemCount = currentQuery.Count();
 
            if (EnableLazySorting)
            { currentQuery = AddSortingLogicToQuery(currentQuery, sortExpression); }
 
            if (ShouldApplyDefaultSort(sortExpression))
            { currentQuery = AddDefaultSortingLogic(currentQuery); }
             
            if (EnableLazyPaging)
            { currentQuery = AddPagingLogicToQuery(currentQuery); }
 
            base.DataSource = currentQuery;
        }
 
        private bool ShouldApplyDefaultSort(string sortExpression)
        {
            return !string.IsNullOrEmpty(DefaultSortColumn) && string.IsNullOrEmpty(sortExpression);
        }
 
        protected virtual IQueryable AddDefaultSortingLogic(IQueryable currentQuery)
        {
            return currentQuery.OrderBy(string.Format("{0} descending", DefaultSortColumn));
        }
 
        protected virtual IQueryable AddFilteringLogicToQuery(IQueryable query, string filterExpression)
        {
            if(string.IsNullOrEmpty(filterExpression))
            { return query; }
 
            var filterExpressionParsed = filterExpression.Replace("ToTitleCase", "ToUpper");
            return query.Where(filterExpressionParsed);
        }
 
        protected virtual IQueryable AddSortingLogicToQuery(IQueryable query, string sortExpression)
        { return string.IsNullOrEmpty(sortExpression) ? query : query.OrderBy(sortExpression); }
 
        protected virtual IQueryable AddPagingLogicToQuery(IQueryable query)
        { return query.Skip(PageSize * CurrentPageIndex).Take(PageSize); }
    }
0
Craig
Top achievements
Rank 1
answered on 23 Jul 2013, 08:05 AM
I have posted the source code for the control in the previous post, it is bound and used just like any normal radgrid, so the only
difference is the EnableLazySorting, EnableLazyPaging, EnableLazyFiltering attributes.

The main function of the control is to take an IQueryable and basically FORCE the query to constrain
the data so that the radgrid becomes a dumb table basically. So the effort of sorting, filtering, paging
is all done server side and the radgrid just displays what it is told. 

Sorting and paging works great, however like mentioned originally filtering is always 1 postback behind where 
it should be.

0
Andrey
Telerik team
answered on 26 Jul 2013, 06:06 AM
Hi,

Since you are extending RadGrid and not using the default behavior of RadGrid what is needed to find the source of issue is to debug the application. However, we are not supporting custom versions of our controls.

As a suggestion you could check whether you are not calling the DataBind() method of RadGrid somewhere in your code, how you are extracting and creating the filter expression and how you are using then this expression.

Other than that I am afraid I could not help much.

Regards,
Andrey
Telerik
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 the blog feed now.
0
Craig
Top achievements
Rank 1
answered on 26 Jul 2013, 09:30 AM
I wouldn't expect you to support my custom code, however as my code delegates to your code I *would* expect you to support that.

The offending section is:

protected override void OnItemCommand(GridCommandEventArgs e)
        {
            if (e.CommandName == FilterCommandName)
            {
                CurrentFilterExpression = MasterTableView.FilterExpression;
                Rebind();
            }
             
            base.OnItemCommand(e);
        }

Which is basically tacking on to your OnItemCommand, checking if the command is a filter, then if  so save the current filter, then rebind the underlying data source (which will in turn use the saved FilterExpression).

However in this scenario the MasterTableView.FilterExpression does not give me the current filter being applied, so if we look at this in isolation, what *should* the MasterTableView.FilterExpression give me in the above scenario.

The answer I would expect would be "It gives you the current filters as an expression to use in sql or linq", however the actual behavior is "It gives you the previous filters applied, and does not include the filter which triggered the OnItemCommand".

So ultimately I just want to get ALL filters being applied to the grid as an expression, if we ignore my custom inherited class and just look at he fundamental problem of getting the most up to date filters and saving them, how should I get this information from a radgrid?
0
Andrey
Telerik team
answered on 31 Jul 2013, 06:44 AM
Hello,

Does the problem replicates when you use RadGrid from the assembly we provide? If the issue still replicate when you remove your custom code, please open a formal support ticket and attach the project that replicates the issue to it. Thus we will be able to test/debug the project locally and let you know what is the problem.

I am attaching a sample project that uses the standard RadGrid instance and it is working as expected on my side. Give it a try and you should not have problems.

Regards,
Andrey
Telerik
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 the blog feed now.
0
Craig
Top achievements
Rank 1
answered on 31 Jul 2013, 03:33 PM
Thank you for your example, I have added to it to show the behavior I am seeing and can replicate it.

Our use cases are completely different, as in our scenario all data related activities are carried out server side, such as filtering, paging, sorting. However in your example it is all done automatically by your control. So in our case any time something changes, be it a filter changing or a page moving, we need to requery the database with the new information (sortexpression, filterexpression, pagecount, pageindex).

Anyway that all aside I have attached an example which shows what I am seeing. If you load it up and do a filter such as CustomerId Contains "a", you will see that the prerender and the datasource see the up to date filter expression, however the ItemAction (filter command) does not see the correct filter. Then if you change this filter to contain "b" you will see that the ItemAction is seeing an out of date FilterExpression.

As in our scenario we rebind when this occurs (which may need changing, however I dont know what to change it to), so we are always seeing out of date filter expressions.

I am unable to upload this project as you only accept image attachments, and our support term has expired as the controls were purchased by the client I am working with about 2 years ago. So if you use the project (or at least the files) you provided on your previous post and then change the Default.aspx file to this:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="TelerikRadGridIssue.WebForm1" %>
<%@ Register TagPrefix="telerik" Namespace="Telerik.Web.UI" Assembly="Telerik.Web.UI, Version=2011.3.1305.0, Culture=neutral, PublicKeyToken=29ac1a93ec063d92" %>
 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 
<head runat="server">
    <title></title>
</head>
<body>
    <form runat="server">
         
            <div id="prerenderFilterContainer">
                <h2>Pre-render filter data:</h2>
                <label runat="server" id="preRenderfilterOutput">-No Filter Yet</label>
            </div>
            <div id="rebindingFilterContainer">
                <h2>Rebind filter data:</h2>
                <label runat="server" id="rebindingFilterOutput">-No Filter Yet</label>
            </div>
            <div id="dataSourceFilterContainer">
                <h2>Datasource filter data:</h2>
                <label runat="server" id="datasourceFilterOutput">-No Filter Yet</label>
            </div>
            <div id="filteringFilterContainer">
                <h2>Filtering filter data:</h2>
                <label runat="server" id="filteringFilterOutput">-No Filter Yet</label>
            </div>
    <telerik:RadScriptManager ID="RadScriptManager1" runat="server">
            <Scripts>
                <asp:ScriptReference Assembly="Telerik.Web.UI" Name="Telerik.Web.UI.Common.Core.js"></asp:ScriptReference>
                <asp:ScriptReference Assembly="Telerik.Web.UI" Name="Telerik.Web.UI.Common.jQuery.js"></asp:ScriptReference>
                <asp:ScriptReference Assembly="Telerik.Web.UI" Name="Telerik.Web.UI.Common.jQueryInclude.js"></asp:ScriptReference>
            </Scripts>
        </telerik:RadScriptManager>
        <telerik:RadGrid ID="RadGrid1" runat="server" ShowStatusBar="true"
            AutoGenerateColumns="False" PageSize="30" AllowSorting="True" AllowMultiRowSelection="False" MasterTableView-HierarchyLoadMode="ServerBind"
            AllowPaging="True" GridLines="None" AllowAutomaticDeletes="True" AllowAutomaticInserts="True" AllowMultiRowEdit="true" AllowFilteringByColumn="true"
            AllowAutomaticUpdates="True" OnDataBinding="RadGrid1_DataBinding" OnItemCommand="RadGrid1_OnItemCommand">
            <PagerStyle Mode="NumericPages"></PagerStyle>
            <MasterTableView DataKeyNames="CustomerID" AllowMultiColumnSorting="True" AllowFilteringByColumn="true"
                Width="100%" CommandItemDisplay="Top" Name="Customers">
                <CommandItemTemplate>
                    <telerik:RadComboBox ID="RadComboBox1" runat="server" CheckBoxes="true" EnableCheckAllItemsCheckBox="true"
                        Width="170" EmptyMessage="Select Options" DropDownAutoWidth="Enabled">
                        <Items>
                            <telerik:RadComboBoxItem Text="Conductivity" />
                            <telerik:RadComboBoxItem Text="Resistance" />
                            <telerik:RadComboBoxItem Text="Chemistry" />
                        </Items>
                    </telerik:RadComboBox>
                </CommandItemTemplate>
                <Columns>
                    <telerik:GridEditCommandColumn ButtonType="ImageButton" UniqueName="EditCommandColumn">
                        <HeaderStyle Width="20px"></HeaderStyle>
                        <ItemStyle CssClass="MyImageButton"></ItemStyle>
                    </telerik:GridEditCommandColumn>
                    <telerik:GridBoundColumn SortExpression="CustomerID" HeaderText="CustomerID" HeaderButtonType="TextButton"
                        DataField="CustomerID" UniqueName="CustomerID" MaxLength="5">
                    </telerik:GridBoundColumn>
                    <telerik:GridBoundColumn SortExpression="ContactName" HeaderText="Contact Name" HeaderButtonType="TextButton"
                        DataField="ContactName" UniqueName="ContactName">
                    </telerik:GridBoundColumn>
                    <telerik:GridBoundColumn SortExpression="CompanyName" HeaderText="Company" HeaderButtonType="TextButton"
                        DataField="CompanyName" UniqueName="CompanyName">
                    </telerik:GridBoundColumn>
                    <telerik:GridBoundColumn SortExpression="Address" HeaderText="Address" HeaderButtonType="TextButton"
                        DataField="Address" UniqueName="Address">
                    </telerik:GridBoundColumn>
                    <telerik:GridNumericColumn UniqueName="NumericColumn">
                    </telerik:GridNumericColumn>
                </Columns>
            </MasterTableView>
        </telerik:RadGrid>     
        <asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:NorthwindConnectionString %>"
            DeleteCommand="DELETE FROM [Customers] WHERE [CustomerID] = @CustomerID" InsertCommand="INSERT INTO [Customers] ([CustomerID], [CompanyName], [ContactName], [Address]) VALUES (@CustomerID, @CompanyName, @ContactName, @Address)"
            SelectCommand="SELECT * FROM [Customers]" UpdateCommand="UPDATE [Customers] SET [CompanyName] = @CompanyName, [ContactName] = @ContactName, [Address] = @Address WHERE [CustomerID] = @CustomerID">
            <DeleteParameters>
                <asp:Parameter Name="CustomerID" Type="String"></asp:Parameter>
            </DeleteParameters>
            <InsertParameters>
                <asp:Parameter Name="CustomerID" Type="String"></asp:Parameter>
                <asp:Parameter Name="CompanyName" Type="String"></asp:Parameter>
                <asp:Parameter Name="ContactName" Type="String"></asp:Parameter>
                <asp:Parameter Name="Address" Type="String"></asp:Parameter>
            </InsertParameters>
            <UpdateParameters>
                <asp:Parameter Name="CompanyName" Type="String"></asp:Parameter>
                <asp:Parameter Name="ContactName" Type="String"></asp:Parameter>
                <asp:Parameter Name="Address" Type="String"></asp:Parameter>
                <asp:Parameter Name="CustomerID" Type="String"></asp:Parameter>
            </UpdateParameters>
        </asp:SqlDataSource>
        </form>
</body>
</html>

Then change the code behind to this:
using System;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using Telerik.Web.UI;
 
namespace TelerikRadGridIssue
{
    public partial class WebForm1 : System.Web.UI.Page
    {
        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);
            RadGrid1.PreRender += RadGrid1_PreRender;
            RadGrid1.NeedDataSource += RadGrid1_NeedDataSource;
        }
 
        protected void RadGrid1_NeedDataSource(object sender, GridNeedDataSourceEventArgs e)
        {
            datasourceFilterOutput.InnerText = RadGrid1.MasterTableView.FilterExpression;
            RadGrid1.DataSource = GetDataTable("SELECT * FROM [Customers]");
        }
 
        protected void RadGrid1_PreRender(object sender, EventArgs e)
        {
            preRenderfilterOutput.InnerText = RadGrid1.MasterTableView.FilterExpression;
        }
 
        protected void RadGrid1_DataBinding(object sender, EventArgs e)
        {
            rebindingFilterOutput.InnerText = RadGrid1.MasterTableView.FilterExpression;
        }
         
        public DataTable GetDataTable(string query)
        {
            String ConnString = ConfigurationManager.ConnectionStrings["NorthwindConnectionString"].ConnectionString;
            SqlConnection conn = new SqlConnection(ConnString);
            SqlDataAdapter adapter = new SqlDataAdapter();
            adapter.SelectCommand = new SqlCommand(query, conn);
 
            DataTable myDataTable = new DataTable();
 
            conn.Open();
            try
            {
                adapter.Fill(myDataTable);
            }
            finally
            {
                conn.Close();
            }
 
            myDataTable.Rows.InsertAt(myDataTable.NewRow(), 0);
            SqlParameter customerID = new SqlParameter("CustomerID", "ALFKI");
            query = "SELECT * FROM [Customers] WHERE CustomerID = '" + customerID.Value + "'";
            adapter.SelectCommand = new SqlCommand(query, conn);
            conn.Open();
            try
            {
                adapter.Fill(0, 1, myDataTable);
            }
            finally
            {
                conn.Close();
            }
            return myDataTable;
        }
 
        protected void RadGrid1_OnItemCommand(object sender, GridCommandEventArgs e)
        {
            if (e.CommandName == "Filter" || e.CommandName == "ClearFilter")
            { filteringFilterOutput.InnerText = RadGrid1.MasterTableView.FilterExpression; }
        }
    }
}


Then run it you should see that the FilterExpression is not up to date in the callback for a filter occurring, that is the exact issue which stops me from filtering, as we use this to indicate the user is filtering and the data needs to be requeried with the new filter expression, which will be incorrect.
0
Andrey
Telerik team
answered on 05 Aug 2013, 08:51 AM
Hello,

I was able to replicate the issue with your directions.

The confusion in your case come from the fact that you are trying to access the filter expression on the ItemCommand event. This event is raised too early in the life-cycle of the control and the Grid has not yet created the new expression.

The earliest possible place where you could access the new filter expression is LoadComplete event. Before that event you will see the old filter expression, because between Init and Load the ViewState is restored and if you try to change the control structure you would get an exception that ViewState could not be restored.

I hope the situation is clear now.

Regards,
Andrey
Telerik
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 the blog feed now.
0
Craig
Top achievements
Rank 1
answered on 05 Aug 2013, 04:04 PM
Thanks for the response, I tried the OnLoad event, however it must occur not occur before the rebind takes place :(

As the problem from my end is that I need to explicitly rebind when the user changes the filters, and the only way I could see to do that was wait for the OnItemCommand and then Rebind() if the command name is "filter". So is there any other way in the lifecycle I can trigger a rebind after the user changes the filter?

So is there any other way other than the ItemCommand events to find out if the user is doing a filter?

== Edit ==

I notice when de-compiling the source there are a few methods around re-creating the filter expression, such as "UpdateFilterControl" and "CreateFilterableContext", so is there any way to *fake* a grid re-load so it would re-create the filterexpression at a given point in time via reflection into private methods?
0
Andrey
Telerik team
answered on 08 Aug 2013, 10:34 AM
Hello,

No matter where you will get the new expression you could always call the Rebind() method of RadGrid. The Rebind() method assure that all the changes would be applied to the control.

What I am unable to understand is what you want to do after you get the new filter expression. Could you elaborate on the part where you get the filter expression and then how you want to proceed. If I know that I would be able to give more accurate suggestions on how to achieve your goal.

Regards,
Andrey
Telerik
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 the blog feed now.
0
Craig
Top achievements
Rank 1
answered on 08 Aug 2013, 03:11 PM
I have posted the code used in my control above in one of the original controls. If you look at the OnDataBinding method in my example you can see what happens.

At a high level we are just using the radgrid to display data not alter it in any way,
we dont use any of the crud operation functionality, the only reason we are still using
the radgrid rather than a normal webgrid is because of the column sorting and filtering
styling. However we dont actually get the grid to do anything, we just want it to notify
us when a user is sorting, filtering, paging and then we will go off and do the logic 
around those interactions. This is why we are having issues, as the RadGrid wants to
do all those actions, and I don't want it to.

I want the users to enter their filters into the grid as per normal, but then I want to
intercept the filtering event before the control tries to filter the given data set in memory.
This is where the problem comes in as there only seems to be one way to find out if a user is 
trying to filter data and you cannot get the filter expression at that point. This happens for
all data changing actions, when a user pages or sorts we rebind the data source explicitly, 
as we recompose the linq query, so the server only returns 100 rows rather than 2 million then 
filtering them in memory.

Anyway to answer your original question more specifically, once a filter action has occurred
we forcibly rebind and use the filter expression to re-compose our base query. We cannot allow 
the control to filter itself as it attempts to pull down over 2 million records and crashes the 
system.

The main bit of code from my example to look at is this:

protected virtual void OverrideDataSource(string filterExpression, string sortExpression)
        {
            var currentQuery = base.DataSource as IQueryable;
  
            if (EnableLazyFiltering)
            { currentQuery = AddFilteringLogicToQuery(currentQuery, filterExpression); }
  
            base.VirtualItemCount = currentQuery.Count();
  
            if (EnableLazySorting)
            { currentQuery = AddSortingLogicToQuery(currentQuery, sortExpression); }
  
            if (ShouldApplyDefaultSort(sortExpression))
            { currentQuery = AddDefaultSortingLogic(currentQuery); }
              
            if (EnableLazyPaging)
            { currentQuery = AddPagingLogicToQuery(currentQuery); }
  
            base.DataSource = currentQuery;
        }

So we pass in the current filter when we do the underlying rebind, but it will be "" in this 
instance as the OnItemCommand will not have an up to date filter expression. If you look at the
third post in this thread you will see all the source code (as of a few weeks back) for how 
we use the rad control. As we are just hooking into the exposed events, nothing fancy.

0
Andrey
Telerik team
answered on 13 Aug 2013, 07:46 AM
Hello,

Thank you for the clarification. It helped me to understand better your goal.

May I suggest to use the RadGrid DataBinding event instead of Page DataBinding event. In the RadGrid DataBinding event you could get the new filter expression and thus you could call the OverrideDataSource method with the correct parameters.

Regards,
Andrey
Telerik
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 the blog feed now.
0
Craig
Top achievements
Rank 1
answered on 13 Aug 2013, 08:02 AM
I am overriding the RadGrids "OnDataBinding" method, which should be the same thing should it not? or is there some other way I should approach this, as im not binding to a pages events anywhere, its all done on the RadGrid (mainly because its and inherited class and knows nothing of the page).
0
Andrey
Telerik team
answered on 15 Aug 2013, 01:31 PM
Hello,

OnDataBinding event of RadGrid is not fired after filtering operation is performed. In order to get the latest filter expression you should use DataBound event instead.

I made a sample project to illustrate the approach you need to use. Give it a try and you should not have problems.

Regards,
Andrey
Telerik
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 the blog feed now.
0
Craig
Top achievements
Rank 1
answered on 16 Aug 2013, 02:12 PM
I will go look at that, but the name implies the data has already been bound, so at this point I would have to fire another rebind, but the overhead of a double data bind would not be too bad in this instance. I am manually firing a rebind from the filter event being raised, which triggers the data binding, but will post back once I have tried your proposed solution.
0
Andrey
Telerik team
answered on 19 Aug 2013, 11:37 AM
Hi,

Yes, you may need to rebind again the Grid because the filter expression property might be updated after the data has already been filtered.

I hope it would not cost you too much efforts.

Regards,
Andrey
Telerik
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 the blog feed now.
0
Craig
Top achievements
Rank 1
answered on 22 Aug 2013, 07:45 AM
I have tried explicitly rebinding when in OnDataBound (override) but even then the FilterExpression of the MasterTableView is empty, so looks like this is not the answer. Just so we are all on the same page, it is happening within an RadAjaxPanel so its all updated via ajax, could that also explain why it is not updating when you would expect it to have?
0
Andrey
Telerik team
answered on 22 Aug 2013, 11:24 AM
Hello,

I made a sample project to test your case. On my side the application is working as expected. Give it a try and you let me know whether it is working on your side.

Regards,
Andrey
Telerik
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 the blog feed now.
0
Craig
Top achievements
Rank 1
answered on 30 Aug 2013, 02:35 PM
Sorry for the delay in responding, I have not had time to work on this technical debt.

I tried your example and if I trigger a rebind from inside the OnItemCommand the following databound event contains the empty filter expression, so it is only when it goes to do its default page rebind it has the normal filter expression.
0
Kostadin
Telerik team
answered on 04 Sep 2013, 09:32 AM
Hi Craig,

I tried firing Rebind() method from within the ItemCommand event and on my side the filter expression is not empty and contains the current one. I prepared a video where I demonstrates how it's working on my end. Please check it out and let me know how it differs from your real setup.

Regards,
Kostadin
Telerik
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 the blog feed now.
0
Craig
Top achievements
Rank 1
answered on 12 Sep 2013, 10:58 AM
Thanks for the screencast, was the same way I was testing it... HOWEVER!

Our difference comes from how our page is using the controls, if you were to debug in that scenario you show and put a breakpoint on line 18, it should be fired 2-3 times depending on how your page is refreshing the grid so lets take the 2 time example.

- First time will be from the explicit Rebind from the FilterCommand, for me in this scenario the filter expression is incorrect
- Second time seems to be some automatic refresh of the page which does some implicit rebind (in our real scenario we dont get this behaviour), in this scenario the filter expression is correct

So as your screencast only shows the result, it will most likely have done a rebind 2-3 times under the hood, but you only see the final result, which in your case is correct because for some reason your grid is setup to do a rebind after the ajax request returns, whereas in our real situation this implicit rebind does not seem to occur. 

If you run the above test again with the debugger and see if you get the same behaviour then maybe you can tell me what is causing the final successful rebind to occur and I can try to get our grid to behave the same way.

Thanks again
0
Kostadin
Telerik team
answered on 17 Sep 2013, 08:39 AM
Hi Craig,

I prepared another video which demonstrates how it behaves on my side and I will try to explain how it works. When the page is initially loaded the DataBound event is fired which allows you to populate the grid with data. When a filter command has been executed the page will postback after the ItemCommand event which will fires DataBound event again. Note that the Rebind() method is only used to populate the grid with the newly data or in case when no postback occurs. You could try change the label text on PreRender event handler which fires later in the page life cycle. I am not completely sure why the postback doesn't occurs on your end. I assume that you are receiving an exception which prevent the normal work of the grid. Please remove the ajax from the page and try again.

Regards,
Kostadin
Telerik
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 the blog feed now.
Tags
Grid
Asked by
Craig
Top achievements
Rank 1
Answers by
Andrey
Telerik team
Craig
Top achievements
Rank 1
Kostadin
Telerik team
Share this question
or