Problem with RadListView, Nested RadGrid and RadDataPager

3 posts, 1 answers
  1. James Daresta
    James Daresta avatar
    59 posts
    Member since:
    Sep 2009

    Posted 06 Jan 2011 Link to this post

    I am having a problem in using the RadListView with a nested RadGrid and the RadDataPager. Basically when the page loads it works fine, but as soon as I click on the pager to advance to the next page I get the following error.

    System.ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection.
    Parameter name: index

    Line 64: 
    Line 65:         row = dt.NewRow();
    Line 66: row["Id"] = (int)parentItem.GetDataKeyValue("Id");Line 67:         row["Description"] = "One";
    Line 68:         dt.Rows.Add(row);

    I have tried for a while now to figure out what is wrong. What I see is the rgPriorActualVolumeValues_NeedDataSource being called twice with the error occuring on the second call. Here is some simple sample code I created. I am using RadControls v. 2010.3.1215.40. Thanks in advance.

    ASPX Page

    <%@ 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">
      
    <head runat="server">
        <title></title>
        <telerik:RadStyleSheetManager id="RadStyleSheetManager1" runat="server" />
    </head>
    <body>
        <form id="form1" runat="server">
        <telerik:RadScriptManager ID="RadScriptManager1" runat="server">
            <Scripts>
                <%--Needed for JavaScript IntelliSense in VS2010--%>
                <%--For VS2008 replace RadScriptManager with ScriptManager--%>
                <asp:ScriptReference Assembly="Telerik.Web.UI" Name="Telerik.Web.UI.Common.Core.js" />
                <asp:ScriptReference Assembly="Telerik.Web.UI" Name="Telerik.Web.UI.Common.jQuery.js" />
                <asp:ScriptReference Assembly="Telerik.Web.UI" Name="Telerik.Web.UI.Common.jQueryInclude.js" />
            </Scripts>
        </telerik:RadScriptManager>
        <script type="text/javascript">
            //Put your JavaScript code here.
        </script>
        <telerik:RadAjaxManager ID="RadAjaxManager1" runat="server">
        </telerik:RadAjaxManager>
       
        <telerik:RadSkinManager ID="RadSkinManager1" Runat="server" Skin="Default">
        </telerik:RadSkinManager>
      
    <table align="center" width="99%" style="table-layout:fixed">
        <tr>
            <td>
                <telerik:RadListView ID="rlvForecastCardView_Item" runat="server" Width="100%" 
                    AllowPaging="true" ItemPlaceholderID="ItemHolder" 
                    DataKeyNames="Id"
                    PageSize="1"
                    onneeddatasource="rlvForecastCardView_Item_NeedDataSource">
                    <LayoutTemplate>
                        <asp:Panel ID="ItemHolder" runat="server" />
                        <telerik:RadDataPager ID="RadDataPager1" runat="server" PagedControlID="rlvForecastCardView_Item"
                            PageSize="1">
                            <Fields>
                                <telerik:RadDataPagerButtonField FieldType="FirstPrev" />
                                <telerik:RadDataPagerButtonField FieldType="Numeric" />
                                <telerik:RadDataPagerButtonField FieldType="NextLast" />
                                <telerik:RadDataPagerTemplatePageField>
                                    <PagerTemplate>
                                        <div style="float: right">
                                            <b>Items
                                                <asp:Label runat="server" ID="CurrentPageLabel" Text="<%# Container.Owner.StartRowIndex+1%>" />
                                                to
                                                <asp:Label runat="server" ID="TotalPagesLabel" Text="<%# Container.Owner.TotalRowCount > (Container.Owner.StartRowIndex+Container.Owner.PageSize) ? Container.Owner.StartRowIndex+Container.Owner.PageSize : Container.Owner.TotalRowCount %>" />
                                                of
                                                <asp:Label runat="server" ID="TotalItemsLabel" Text="<%# Container.Owner.TotalRowCount%>" />
                                                <br />
                                            </b>
                                        </div>
                                    </PagerTemplate>
                                </telerik:RadDataPagerTemplatePageField>
                            </Fields>
                        </telerik:RadDataPager>
      
                    </LayoutTemplate>
                    <ItemTemplate>
                        <table class="ContentTableBordered TableFullWidth" cellspacing="0" cellpadding="4">
                            <tr>
                                <td class="tableSectionLabelCell"><asp:Literal ID="lIdLabel" runat="server" Text="ID"></asp:Literal></td>
                                <td class="tableSectionLabelCell"><asp:Literal ID="lDescriptionLabel" runat="server" Text="Description"></asp:Literal></td>
                            </tr>
                            <tr>
                                <td class="tableSectionDataCell"><%# Eval("Id") %></td>
                                <td class="tableSectionDataCell"><%# Eval("Description") %></td>
                            </tr>
                        </table>                
                        <br />
                        <table class="ContentTableBordered TableFullWidth" cellspacing="0" cellpadding="4">
                            <tr>
                                <td width="33%">
                                    <telerik:RadGrid ID="rgPriorActualVolumeValues" runat="server" 
                                        AllowFilteringByColumn="False" 
                                        AllowPaging="False" 
                                        AllowSorting="false"
                                        ClientSettings-AllowColumnHide="false" 
                                        AutoGenerateColumns="False" 
                                        ShowGroupPanel="false"
                                        ShowFooter="true"
                                        EnableHeaderContextMenu="false"
                                        ViewStateMode="Disabled"
                                        onneeddatasource="rgPriorActualVolumeValues_NeedDataSource">
                                    <MasterTableView
                                        CommandItemDisplay="None">
                                    <RowIndicatorColumn>
                                    <HeaderStyle Width="20px"></HeaderStyle>
                                    </RowIndicatorColumn>
                                    <ExpandCollapseColumn>
                                    <HeaderStyle Width="20px"></HeaderStyle>
                                    </ExpandCollapseColumn>
                                    <Columns>
                                        <telerik:GridBoundColumn DataField="Id" HeaderText="Id" UniqueName="Id">
                                        </telerik:GridBoundColumn>
                                        <telerik:GridBoundColumn DataField="Description" HeaderText="Description" UniqueName="Description">
                                        </telerik:GridBoundColumn>
                                     </Columns>
                                    <NoRecordsTemplate>
                                    <asp:Label ID="lblNoTotalsRecords" runat="server" CssClass="LabelBold" Text="No records for the filtering selections you have chosen."></asp:Label>
                                    </NoRecordsTemplate>
                                    </MasterTableView>
                                    </telerik:RadGrid>
                                 
                                </td>
      
                            </tr>
      
                        </table>
      
      
                      
                    </ItemTemplate>
                </telerik:RadListView>
            </td>
        </tr>
    </table>
      
      
        </form>
    </body>
    </html>

    Code Behind

    using System;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;
      
    using System.Data;
    using System.Configuration;
    using System.Web.Security;
    using System.Web.UI.WebControls.WebParts;
    using System.Web.UI.HtmlControls;
    using Telerik.Web.UI;
      
    public partial class Default : System.Web.UI.Page 
    {
        protected void Page_Load(object sender, EventArgs e)
        {
      
        }
      
        protected void rlvForecastCardView_Item_NeedDataSource(object sender, RadListViewNeedDataSourceEventArgs e)
        {
            DataTable dt = new DataTable();
            DataRow row;
      
      
            dt.Columns.Add("Id", typeof(int));
            dt.Columns.Add("Description", typeof(string));
      
            row = dt.NewRow();
            row["Id"] = 1;
            row["Description"] = "One";
            dt.Rows.Add(row);
      
            row = dt.NewRow();
            row["Id"] = 2;
            row["Description"] = "Two";
            dt.Rows.Add(row);
      
            row = dt.NewRow();
            row["Id"] = 3;
            row["Description"] = "Three";
            dt.Rows.Add(row);
      
            row = dt.NewRow();
            row["Id"] = 4;
            row["Description"] = "Four";
            dt.Rows.Add(row);
      
            rlvForecastCardView_Item.DataSource = dt;
        }
      
        protected void rgPriorActualVolumeValues_NeedDataSource(object source, Telerik.Web.UI.GridNeedDataSourceEventArgs e)
        {
            RadGrid rgPriorActualVolumeValues = (RadGrid)source;
            var parentItem = rgPriorActualVolumeValues.NamingContainer as RadListViewDataItem;
      
      
            DataTable dt = new DataTable();
            DataRow row;
      
      
            dt.Columns.Add("Id", typeof(int));
            dt.Columns.Add("Description", typeof(string));
      
            row = dt.NewRow();
            row["Id"] = (int)parentItem.GetDataKeyValue("Id");
            row["Description"] = "One";
            dt.Rows.Add(row);
      
            row = dt.NewRow();
            row["Id"] = (int)parentItem.GetDataKeyValue("Id");
            row["Description"] = "Two";
            dt.Rows.Add(row);
      
            row = dt.NewRow();
            row["Id"] = (int)parentItem.GetDataKeyValue("Id");
            row["Description"] = "Three";
            dt.Rows.Add(row);
      
            row = dt.NewRow();
            row["Id"] = (int)parentItem.GetDataKeyValue("Id");
            row["Description"] = "Four";
            dt.Rows.Add(row);
      
      
      
            rgPriorActualVolumeValues.DataSource = dt;
        }
      
      
    }


  2. Answer
    Radoslav
    Admin
    Radoslav avatar
    1564 posts

    Posted 12 Jan 2011 Link to this post

    Hi James,

    The described behavior is expected, because after paging the NeedDataSource of the RadListView is fired more later than when a page is initially loaded. In this way the ItemDataBound event of the ListView is called after NeedDataSource of the RadGrid and the error is thrown when GetDataKeyValue() of the ListViewDataItem is called. To achieve the desired functionality you need to add following check into the rgPriorActualVolumeValues_NeedDataSource:
    RadGrid rgPriorActualVolumeValues = (RadGrid)source;
    var parentItem = rgPriorActualVolumeValues.NamingContainer as RadListViewDataItem;
    if (parentItem.DataItem == null)
         return;

    and then call RadGrid's Rebind method into the rlvForecastCardView_Item_ItemDataBound:
    void rlvForecastCardView_Item_ItemDataBound(object sender, RadListViewItemEventArgs e)
      {
          if (e.Item is RadListViewDataItem)
          {
              var grid = (RadGrid)e.Item.FindControl("rgPriorActualVolumeValues");
              grid.Rebind();
          }
      }

    Additionally I am sending you a simple example which demonstrates the desired functionality.

    Best wishes,
    Radoslav
    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.
  3. UI for ASP.NET Ajax is Ready for VS 2017
  4. James Daresta
    James Daresta avatar
    59 posts
    Member since:
    Sep 2009

    Posted 12 Jan 2011 Link to this post

    Thanks. That explains it for me. I have to be honest though and say I already found a work around. Instead of relying on the NeedDataSource for the child items I did the binding in the parent OnItemDataBound event. This achieved what I wanted.

    protected void rlvForecastCardView_Item_ItemDataBound(object sender, RadListViewItemEventArgs e)
    {
        GridFooterItem footerItem;
        RadNumericTextBox newNumTxtBox;
        RadListViewDataItem item = e.Item as RadListViewDataItem;
        RadGrid rgPriorActualVolumeValues = item.FindControl("rgPriorActualVolumeValues") as RadGrid;
        RadGrid rgPriorAccountManagerValues = item.FindControl("rgPriorAccountManagerValues") as RadGrid;
        RadGrid rgPriorManagementAllocationValues = item.FindControl("rgPriorManagementAllocationValues") as RadGrid;
        if (rgPriorActualVolumeValues != null)
        {
            List<ForecastCardViewPriorActualValue> actuals = SalesForecastingController.GetCardViewPriorActualValues(
                SelectedForecastId,
                (Guid)item.GetDataKeyValue("CustomerId"),
                item.GetDataKeyValue("MaterialGroup.MaterialGroupNo").ToString(),
                ucForecastCardView_SalesForecastFilterHeader.Period);
            rgPriorActualVolumeValues.DataSource = actuals;
            rgPriorActualVolumeValues.DataBind();
Back to Top