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

Problem with SEO Paging and ItemDataBound Event

4 Answers 161 Views
Grid
This is a migrated thread and some comments may be shown as answers.
Tundey
Top achievements
Rank 1
Tundey asked on 07 Apr 2011, 03:25 PM
Hello,
I have run into a problem where the ItemDataBound event is fired multiple times whenever the "next page" link is clicked and SEO paging is enabled. But the weird thing is that the first time, it's fired for the items on the first page! The sequence goes like this, once the user clicks "next page":

  • page load
  • need data source
  • item data bound for each item on the first page
  • pre render
  • item data bound for each item on the new page

If I turn off SEO paging, it works as expected 
  • page load
  • need data sourec
  • item data bound for each item on the new page
  • pre render

I am not really sure what I am doing wrong. Here's a sample code to demonstrate:
ASPX
<telerik:RadGrid ID="RadGrid1" runat="server" AllowPaging="True" OnItemDataBound="RadGrid1_ItemDataBound" OnPreRender="RadGrid1_PreRender" PageSize="5" onneeddatasource="RadGrid1_NeedDataSource">
    <MasterTableView DataKeyNames="doc_id">
    </MasterTableView>
    <PagerStyle EnableSEOPaging="true" SEOPagingQueryStringKey="page" />
</telerik:RadGrid>

code behind:
public partial class _Default : System.Web.UI.Page
{
    public class TestData
    {
        public int doc_id{get;set;}
        public string Title{get;set;}
    }
 
    private List<TestData> GetData()
    {
        var data = new List<TestData>();
        for (int i = 1; i < 30; i++) {data.Add(new TestData(){doc_id = i,Title = "Title for " + i});}
        return data;
    }
 
    protected void Page_Load(object sender, EventArgs e)
    {
        Debug.WriteLine("Pageload");
    }
 
    protected void RadGrid1_ItemDataBound(object sender, Telerik.Web.UI.GridItemEventArgs e)
    {
        if (e.Item is GridDataItem)
        {
            Debug.WriteLine("ItemDataBound: " + (e.Item as GridDataItem).GetDataKeyValue("doc_id"));
        }
    }
 
    protected void RadGrid1_PreRender(object sender, EventArgs e)
    {
        Debug.WriteLine("PreRender");
    }
 
    protected void RadGrid1_NeedDataSource(object sender, GridNeedDataSourceEventArgs e)
    {
        Debug.WriteLine("NeedDataSource");
        RadGrid1.DataSource = GetData();
    }
}

4 Answers, 1 is accepted

Sort by
0
Veli
Telerik team
answered on 13 Apr 2011, 07:58 AM
Hello Tundey,

The reason for the ItemDataBound event getting fired twice for every item is because RadGrid rebinds twice when you change the page and SEO paging is enabled. You can note that, when SEO paging is enabled, each page button is turned into a link that navigates to the same URL with the specified page query string key appended. This means that every page reload when changing the page is a GET request. In terms of ASP.NET pages, every page request causes an initial page load (Page.IsPostBack = false).

How RadGrid fits in this scenario? RadGrid databinds automatically on initial load. This happens in the Load stage in the control life cycle. When you change the page, the grid rebinds a second time in the PreRender phase. This is why you get ItemDataBound fire for every item twice - once in the Load stage and once in the PreRender stage.

If you use RadGrid's NeedDataSource to pass the data to the grid, you can feel safe, though. NeedDataSource is not fired twice for a single page request. For the second rebind, RadGrid uses the fetched data from the first databind. If you perform database access in the NeedDataSource event, you can be safe the database won't be hit a second time causing an overhead.

Veli
the Telerik team

Browse the vast support resources we have to jump start your development with RadControls for ASP.NET AJAX. See how to integrate our AJAX controls seamlessly in SharePoint 2007/2010 visiting our common SharePoint portal.

0
Tundey
Top achievements
Rank 1
answered on 13 Apr 2011, 12:36 PM
Thanks for the response. Actually, I wasn't worried about NeedDataSource being called twice. What I was trying to implement was a way to export the contents of a page of the datagrid from another page. For example, say the user clicks on the export button, I wanted to display a dialog (in a radwindow) that lets the user customize the export options (fields to export, # of records to export, format etc). So I needed a way to track which records were currently being displayed by the radgrid so that I can export only those records. So I tried to keep track by using ItemDataBound. It didn't work as I explained before. If you have any suggestions (for determining the records that's currently by a radgrid), that'll be great.
0
Veli
Telerik team
answered on 14 Apr 2011, 08:21 AM
In this case, you can use the PreRenderComplete event of the page to loop through your grid items :

void Page_PreRenderComplete(object sender, EventArgs e)
{
    foreach (GridDataItem item in RadGrid1.MasterTableView.Items)
    {
        Debug.WriteLine("ItemDataBound: " + item.GetDataKeyValue("doc_id"));
    }
}

The event will be fired after the second grid rebind and you will have the final set of data items. Note, however, that if you need to make changes to the grid items, these changes will not be persisted in ViewState, as ViewState is already collected and saved. If your grid is in a user control, you can attach to the Page.PreRenderComplete event from the code-behind file of the user control.

Veli
the Telerik team

Browse the vast support resources we have to jump start your development with RadControls for ASP.NET AJAX. See how to integrate our AJAX controls seamlessly in SharePoint 2007/2010 visiting our common SharePoint portal.

0
Tundey
Top achievements
Rank 1
answered on 14 Apr 2011, 01:20 PM
That works. Thanks.
Tags
Grid
Asked by
Tundey
Top achievements
Rank 1
Answers by
Veli
Telerik team
Tundey
Top achievements
Rank 1
Share this question
or