网上商店的Telerik radgrid分页,在最后一页更改产品数量时中断

时间:2013-09-13 10:43:35

标签: c# asp.net telerik paging radgrid

我的一个网上商店遇到了一些问题。 Telerik radgrid用作购物车并列出购物车中当前的所有产品。 Radgrid上的分页正确地将购物车视图拆分为不同的页面。 当手动尝试更改产品数量时,会发生此问题,但仅当产品位于radgrid的最后一页时,且仅当产品数量小于页面大小限制时才会出现此问题。

我还不能发布图片,所以必须给你一个链接。 图片链接http://i.stack.imgur.com/hfFIx.jpg

我已经认识到,尽管radgrid认为根据radgrid的页面大小总是有一定数量的产品。

崩溃发生在tbQuantity_TextChanged事件处理程序中,当为此页面上不存在但在另一页面上的项目调用var shopItemID = Convert.ToInt32(item.GetDataKeyValue("ID"));时更具体。

例外是

System.ArgumentOutOfRangeException was unhandled by user code
  Message=Index was out of range. Must be non-negative and less than the size of the collection.
Parameter name: index

网格视图代码

<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="ShopItems.ascx.cs" Inherits="Litho.Framework.Web.Modules.Shop.ShopItems" %>
<%@ Register Assembly="Telerik.Web.UI" Namespace="Telerik.Web.UI" TagPrefix="telerik" %>

<telerik:RadGrid
    ID="gvCartItems"
    runat="server"
    AutoGenerateColumns="False" 
    AllowPaging="True"
    PageSize="5"
    Skin="Default"
    GridLines="None"
    AllowFilteringByColumn="False"
    AllowSorting="True" 
    ShowFooter="True"
    OnNeedDataSource="gvCartItems_NeedDataSource" 
    OnItemCreated="gvCartItems_ItemCreated"
    OnItemDataBound="gvCartItems_ItemDataBound"
    OnDeleteCommand="gvCartItems_DeleteCommand">

    <MasterTableView Width="100%" NoMasterRecordsText="Inga artiklar" ShowHeadersWhenNoRecords="false" DataKeyNames="ID">
        <Columns>
            <telerik:GridButtonColumn ButtonType="ImageButton" CommandName="Delete" Text="Radera" UniqueName="DeleteColumn" HeaderStyle-Width="20" />
            <telerik:GridTemplateColumn HeaderText="Antal" HeaderStyle-Width="110px" DataField="Quantity" UniqueName="Quantity" Aggregate="Sum" FooterText="Totalt antal: ">
                <ItemTemplate>
                    <telerik:RadNumericTextBox 
                        ID="tbQuantity"
                        runat="server"
                        AutoPostBack="true"
                        Width="70px" 
                        MinValue="1"
                        Visible="false"
                        ShowSpinButtons="true"
                        IncrementSettings-InterceptArrowKeys="false"
                        NumberFormat-GroupSizes="9"
                        NumberFormat-DecimalDigits="0"
                        IncrementSettings-InterceptMouseWheel="true"
                        NumberFormat-AllowRounding="False"
                        OnTextChanged="tbQuantity_TextChanged">

                        <EnabledStyle HorizontalAlign="Right" />

                    </telerik:RadNumericTextBox>
                        <telerik:RadComboBox ID="ddlQuantity" DataTextField="Quantity" DataValueField="Quantity" Visible="false" runat="server" Width="50px" AutoPostBack="true" OnSelectedIndexChanged="ddlQuantity_SelectedIndexChanged" />
                </ItemTemplate>
            </telerik:GridTemplateColumn>


            <telerik:GridBoundColumn HeaderText="Artnr" ReadOnly="True" DataField="ArticleNumber" UniqueName="ArticleNumber" HeaderStyle-Width="80" />

            <telerik:GridTemplateColumn  HeaderText="Artikel" UniqueName="Title" ShowFilterIcon="false">
                <ItemTemplate>
                    <asp:HyperLink ID="hlTitle" runat="server" />
                </ItemTemplate>
            </telerik:GridTemplateColumn>

            <telerik:GridTemplateColumn HeaderText="a`pris" UniqueName="Price" ShowFilterIcon="false">
                <ItemTemplate>
                    <asp:Label ID="lblUnitprice" runat="server" />
                </ItemTemplate>
            </telerik:GridTemplateColumn>

            <telerik:GridTemplateColumn HeaderText="Totalpris" UniqueName="Totalprice" ShowFilterIcon="false">
                <ItemTemplate>
                    <asp:Label ID="lblTotalPrice" runat="server" />
                </ItemTemplate>
            </telerik:GridTemplateColumn>

        </Columns>
    </MasterTableView>

    <FooterStyle Font-Bold="true" BackColor="#e6e6e6" />

    <PagerStyle Mode="NextPrevAndNumeric" />

    <FilterMenu EnableTheming="True">
        <CollapseAnimation Duration="200" Type="OutQuint" />
    </FilterMenu>

</telerik:RadGrid>

<asp:PlaceHolder ID="phItemSummary" runat="server" />

代码

using System;
using System.Collections.Generic;
using System.Web.UI;
using System.Web.UI.WebControls;
using Litho.Framework.BusinessLayer;
using Litho.Framework.BusinessLayer.Base;
using Litho.Framework.BusinessLayer.Base.Settings;
using Litho.Framework.BusinessLayer.Modules.Shop;
using Litho.Framework.PresentationLayer;
using Litho.Framework.ServiceLayer;
using Telerik.Web.UI;

namespace Litho.Framework.Web.Modules.Shop
{
    public partial class ShopItems : UserControl
    {
        IShopItemHolder _shopItemHolder = null;
        bool _readMode = true;
        SessionHelper _sessionHelper = new SessionHelper();

        #region Public methods

        public void LoadItems(IShopItemHolder shopItemHolder, bool readMode)
        {
            _shopItemHolder = shopItemHolder;
            _readMode = readMode;

            gvCartItems.Rebind();

            loadItemsSummary();
        }

        private void loadItemsSummary()
        {
            phItemSummary.Controls.Clear();

            var ucItemSummary = (ShopItemsSummary)Page.LoadControl("~/Modules/Shop/ShopItemsSummary.ascx");
            ucItemSummary.LoadItemSummary(_shopItemHolder);

            phItemSummary.Controls.Add(ucItemSummary);
        }

        #endregion

        #region Events

        protected void gvCartItems_NeedDataSource(object source, GridNeedDataSourceEventArgs e)
        {
            gvCartItems.DataSource = _shopItemHolder.Items;
        }

        protected void gvCartItems_ItemCreated(object sender, GridItemEventArgs e)
        {
            if (e.Item is GridDataItem)
            {
                var item = (GridDataItem)e.Item;
                var btnDelete = (ImageButton)item["DeleteColumn"].Controls[0];

                btnDelete.ImageUrl = string.Format("~/Base/Themes/{0}/Images/Icons16x16/iconDelete.png", SettingsManager.GetGlobalSettings().AdminTheme);
                btnDelete.Visible = !_readMode;
            }
        }

        protected void gvCartItems_ItemDataBound(object sender, GridItemEventArgs e)
        {
            if (e.Item is GridDataItem)
            {
                var shopItem = (IShopItem)e.Item.DataItem;

                var hlTitle = (HyperLink)e.Item.FindControl("hlTitle");
                var lblUnitPrice = (Label)e.Item.FindControl("lblUnitprice");
                var lblTotalPrice = (Label)e.Item.FindControl("lblTotalPrice");

                if (!shopItem.IsExternal)
                {
                    var tbQuantity = (RadNumericTextBox)e.Item.FindControl("tbQuantity");
                    tbQuantity.ShowSpinButtons = !_readMode;
                    tbQuantity.Text = shopItem.Quantity.ToString();
                    tbQuantity.Visible = true;
                    tbQuantity.Enabled = !_readMode;
                }
                else
                {
                    if (!_readMode)
                    {
                        var ddlQuantity = (RadComboBox)e.Item.FindControl("ddlQuantity");
                        ddlQuantity.DataSource = shopItem.PriceCollection;
                        ddlQuantity.DataBind();
                        ddlQuantity.SelectedValue = shopItem.Quantity.ToString();
                        ddlQuantity.Visible = true;
                    }
                }

                if (!shopItem.IsExternal)
                {
                    var parameters = new Dictionary<string, string>();
                    parameters.Add(KeyMaster.RequestParamsNames.Modules.Shop.PRODUCT_ID, shopItem.ID.ToString());

                    hlTitle.NavigateUrl = new FWContent().GetContentUrl(ModuleIDConstant.SHOP, ContentIDConstant.Shop.PRODUCT_VIEW, parameters);
                }

                hlTitle.Text = shopItem.Title;

                lblUnitPrice.Text = shopItem.Price.ToString("0.00") + " SEK";
                lblTotalPrice.Text = shopItem.GetCost(false).ToString("0.00") + " SEK";
            }
        }

        protected void tbQuantity_TextChanged(object sender, EventArgs e)
        {
            if (!_readMode)
            {
                RadNumericTextBox tbQuantity;

                foreach (GridDataItem item in gvCartItems.Items)
                {
                    if (item is GridDataItem)
                    {
                        tbQuantity = item.FindControl("tbQuantity") as RadNumericTextBox;

                        var shopItemID = Convert.ToInt32(item.GetDataKeyValue("ID"));
                        var shopItem = _sessionHelper.CurrentCart.CartItems.Find(x => x.ID == shopItemID);

                        if (!shopItem.IsExternal)
                        {
                            _sessionHelper.CurrentCart.CartItems.Find(x => x.ID == shopItemID).Quantity = Convert.ToInt32(tbQuantity.Text);
                            _sessionHelper.CurrentCart.CartItems.Find(x => x.ID == shopItemID).TotalPrice = _sessionHelper.CurrentCart.GetItemCost(shopItemID, false);
                            _shopItemHolder = _sessionHelper.CurrentCart;
                        }
                    }
                }

                loadItemsSummary();
                gvCartItems.Rebind();
            }
        }

        protected void gvCartItems_DeleteCommand(object source, GridCommandEventArgs e)
        {
            if (!_readMode)
            {
                var cartItemID = (int)e.Item.OwnerTableView.DataKeyValues[e.Item.ItemIndex]["ID"];
                _sessionHelper.CurrentCart.DeleteItem(cartItemID);
                _shopItemHolder = _sessionHelper.CurrentCart;

                if (_sessionHelper.CurrentCart.Items.Count == 0)
                {
                    Response.Redirect(new FWContent().GetContentUrl(ModuleIDConstant.SHOP, ContentIDConstant.Shop.CART));
                }
                else
                {
                    gvCartItems.Rebind();
                    loadItemsSummary();
                }
            }
        }

        protected void ddlQuantity_SelectedIndexChanged(object sender, EventArgs e)
        {
            RadComboBox ddlQuantity;

            foreach (GridDataItem item in gvCartItems.Items)
            {
                if (item is GridDataItem)
                {
                    ddlQuantity = item.FindControl("ddlQuantity") as RadComboBox;

                    var cartItemID = Convert.ToInt32(item.GetDataKeyValue("ID"));
                    var cartItem = _sessionHelper.CurrentCart.CartItems.Find(x => x.ID == cartItemID);

                    if (cartItem.IsExternal)
                    {
                        cartItem.Quantity = Convert.ToInt32(ddlQuantity.Text);
                        cartItem.TotalPrice = getProductPrice(cartItem);
                    }
                }
            }

            loadItemsSummary();

            gvCartItems.Rebind();
        }

        #endregion

        private double getProductPrice(CartItem cartitem)
        {
            foreach (var price in cartitem.PriceCollection)
            {
                if (price.Quantity == cartitem.Quantity)
                {
                    return price.Price;
                }
            }

            throw new Exception(); // todo lägg till customexception 
        }
    }
}

提前致谢!

修改 小更新,我一直在尝试使用CustomPaging,但没有运气,所以我仍然使用已发布的代码。 我觉得奇怪的是,分页工作现在应该如此,只是当我在最后一页上更改它崩溃的数量时。

1 个答案:

答案 0 :(得分:2)

Telerik的那些人帮助了我,问题在于我正在查看所有项目,而不仅仅是数量发生变化的项目。

更新了 tbQuantity_TextChanged

protected void tbQuantity_TextChanged(object sender, EventArgs e)
    {
        if (!_readMode)
        {
            RadNumericTextBox tbQuantity = (RadNumericTextBox)sender;
            GridDataItem dataItem = (GridDataItem)tbQuantity.NamingContainer;

            var shopItemID = (int)dataItem.GetDataKeyValue("ID");
            var shopItem = _sessionHelper.CurrentCart.CartItems.Find(x => x.ID == shopItemID);

            if (!shopItem.IsExternal)
            {
                _sessionHelper.CurrentCart.CartItems.Find(x => x.ID == shopItemID).Quantity = Convert.ToInt32(tbQuantity.Text);
                _sessionHelper.CurrentCart.CartItems.Find(x => x.ID == shopItemID).TotalPrice = _sessionHelper.CurrentCart.GetItemCost(shopItemID, false);
                _shopItemHolder = _sessionHelper.CurrentCart;
            }

            loadItemsSummary();
            gvCartItems.Rebind();
        }
    }