【问题标题】:Capturing changed values from a Repeater on postback在回发时从中继器捕获更改的值
【发布时间】:2011-07-26 18:59:29
【问题描述】:

这困扰着我,我已经阅读了无数的解决方案,但似乎都有些不对劲。我有一个中继器,每个项目有 2 个下拉菜单和一些项目。这些都有用户可以选择的潜在值 0-8,我想在用户单击页面底部的按钮时在回发中收集数据。

    <asp:Repeater ID="rptPricing" runat="server" OnItemDataBound="rptPricing_OnItemDataBound">
    <ItemTemplate>
        <div class="Row clear">
            <div class="Column Cat"><%# ((Price)Container.DataItem).AgeCategory %></div>
            <div id="dWasPrice" runat="server" class="Column Was">
                <asp:Literal ID="litPreviousPrice" runat="server" /><span class="strike"></span>
            </div>
            <div class="Column Now">$<%# ((Price)Container.DataItem).FullPrice %></div>
            <div class="Column Deposit">
                <asp:DropDownList ID="ddlCountForPart" runat="server" skucode="<%# ((Price)Container.DataItem).PartHeaderCode %>">
                    <asp:ListItem Text="0" Value="0"></asp:ListItem>
                    <asp:ListItem Text="1" Value="1"></asp:ListItem>
                    <asp:ListItem Text="2" Value="2"></asp:ListItem>
                    <asp:ListItem Text="3" Value="3"></asp:ListItem>
                    <asp:ListItem Text="4" Value="4"></asp:ListItem>
                    <asp:ListItem Text="5" Value="5"></asp:ListItem>
                    <asp:ListItem Text="6" Value="6"></asp:ListItem>
                    <asp:ListItem Text="7" Value="7"></asp:ListItem>
                    <asp:ListItem Text="8" Value="8"></asp:ListItem>
                </asp:DropDownList>                        
            </div>
            <div class="Column Full">
                <asp:DropDownList ID="ddlCountForFull" runat="server" skucode="<%# ((Price)Container.DataItem).FullHeaderCode %>">
                    <asp:ListItem Text="0" Value="0"></asp:ListItem>
                    <asp:ListItem Text="1" Value="1"></asp:ListItem>
                    <asp:ListItem Text="2" Value="2"></asp:ListItem>
                    <asp:ListItem Text="3" Value="3"></asp:ListItem>
                    <asp:ListItem Text="4" Value="4"></asp:ListItem>
                    <asp:ListItem Text="5" Value="5"></asp:ListItem>
                    <asp:ListItem Text="6" Value="6"></asp:ListItem>
                    <asp:ListItem Text="7" Value="7"></asp:ListItem>
                    <asp:ListItem Text="8" Value="8"></asp:ListItem>
                </asp:DropDownList>
            </div>
        </div>
    </ItemTemplate>
</asp:Repeater>

这里是绑定。

private void BindDetails()
{
    SetDiscountContent();

    rptPricing.DataSource = _Detail.Prices;
    rptPricing.DataBind();
}

这里是数据不存在的地方。

if ( IsPostBack && UIControlUtil.GetPostBackControl(Page) == lnkAddToCart)
{
    //populate the cart without javascript
    //find the drop down with items selected and create Order Elements
    try
    {
        var orders = new Order[0];
        foreach (RepeaterItem item in rptPricing.Items)
        {
            var dl = item.FindControl("ddlCountForFull");
            if (dl != null)
            {
                Array.Resize(ref orders, orders.Length + 1);
                orders[orders.Length - 1] = new Order() {
                    Quantity = Convert.ToInt32(dl.SelectedValue),
                    Sku = dl.Attributes["skucode"]};

我尝试将调用从PageLoad 移动到BindDetails()OnInit 并使用回发标志。我也玩过ViewState 标志,但无济于事。

编辑(添加页面加载),请注意我已将其移至 OnInit。

 protected void Page_Load(object sender, EventArgs e)
    {

        if (ContentItem == null) return;

        if (!IsPostBack)
        {
            var control = (ContentManagement.Library.Sitecore.PreDefinedControl)ContentItem;
            _Detail = (Details)control.DataElements[0];
            BindDetails();
        }

        if (ShoppingCartHelper.GetProductsOfTInCart<blah>() > 8)
        {
            lnkAddToCart.Enabled = false;
            lnkAddToCart.CssClass = lnkAddToCart.CssClass + " disabled cartmax";
        }
    }

【问题讨论】:

  • “数据不存在” - 你的意思是item.FindControl("ddlCountForFull") 为空,还是dl.SelectedValue 为空?
  • 另外,var orders = new Order[0];,然后orders[orders.Length - 1] = new Order() 会在运行时导致错误。
  • 没有项目,所以调用 FindControl 毫无意义,如果我在回发时重新绑定,则有值,但选择的值为 0。

标签: c# asp.net data-binding postback repeater


【解决方案1】:

首先确保你正在做一个:

if (!IsPostBack)
{
    BindDetails();
}

这将确保您不会与每个回发绑定并丢失您的数据。

另外,我不明白需要:

if ( IsPostBack && UIControlUtil.GetPostBackControl(Page) == lnkAddToCart)

为什么不只为ButtonLinkButton 实现OnClick 处理程序,然后移动所有代码以将数据从重复项中提取到处理程序中?

还要确保ViewState 已启用,否则您将无法遍历Repeater 以查找更改的值。

编辑:

检查您是否未在存在Repeater 的容器中禁用ViewState。您应该拥有数据。您不这样做的唯一原因是,如果 ViewState 在控件或其父级之一上被禁用,或者您正在以某种方式(例如重新绑定)擦除值。您能否发布更多您的代码,例如您的 Page_Load 以及之后会发生的任何事件?

尝试在Repeater 之后放置TextBox 并在其中输入soem 文本,然后发布您的Repeater。您能看到您输入的TextBox 中的文字吗?如果不是,则父控件已禁用 ViewState 或在页面级别。如果您可以看到该值,那么您在某处无意中重新绑定到Repeater 并清除了您的数据。您需要在执行绑定的位置放置一个断点,并确保在回发时不会发生。

目前我无法为您提供更多帮助。

【讨论】:

  • 我根据您的建议进行了更改,无论我使用 OnClick 事件处理程序还是其他方法都没有区别。结果是一样的,除非我重新绑定,否则 rptPricing 没有 Items 也没有 Controls。 ViewState 已启用,看起来好像正在跟踪它
  • 是的,唯一的容器是viewstate开启的panel,DropDown、Repeater、Panel上的EnableViewState的值都设置为true,IsTrackingViewState的值为true。我添加了我的页面加载和一些 cmets。文本框日期存在。
  • 我今天早上重新访问,如果我取消自定义属性,一切正常。我的前端人员更喜欢使用这些属性,但我想需要一个不同的解决方案,这个功能在 4.0 中会有所不同吗?
  • 我把它们加回去了,它仍然有效。诡异的。也许今天早上只是一个新鲜的眼睛
  • @Rob 新鲜的眼睛总是有帮助的 :) 在你的 Page_Load 中你有:`lnkAddToCart.CssClass = lnkAddToCart.CssClass + "disabled cartmax"` 这看起来很奇怪,因为在一些帖子支持你链接类将有大量重复的disable cartmax 定义。您的链接将通过ViewState 保留CssClass 属性,因此每次返回您的if 被触发的位置,它可能会多次附加数据。此外,我很少使用OnInit。请记住 ViewState 是在 OnInit 之后但在 Page_Load 之前加载的,所以这可能是您的问题。
猜你喜欢
  • 2018-11-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-18
  • 2017-02-02
  • 2017-02-21
  • 1970-01-01
相关资源
最近更新 更多