【问题标题】:asp.net checkbox not checked on postback回发时未选中 asp.net 复选框
【发布时间】:2017-07-28 21:55:26
【问题描述】:

我知道有很多关于此的问题,但我无法在我的情况下找到答案。

案例:我在页面上有一个下拉菜单和一个占位符,并且根据所选选项,相关内容被加载。在内容 3 中,我有一个复选框,它不会返回正确的选中状态。

问题是下拉菜单会进行回发,最重要的是,当内容加载时,我正在对按钮单击进行另一次回发。

示例案例:

家长控制:

public class MyAccount : BaseAuthControl
{
    protected PlaceHolder phContentMA;

    protected override void Page_Load(object sender, EventArgs e)
    {
        base.Page_Load(sender, e);  

        LoadStage(3);            
    }

    private void LoadStage(int index)
    {
        switch (index)
        {
            case 1:
                var oh = Page.LoadControl("OrderHistory");
                phContentMA.Controls.Add(oh);
                break;
            case 2:
                var st = Page.LoadControl("Statement");
                phContentMA.Controls.Add(st);
                break;
            case 3:
                var pa = Page.LoadControl("ProductAnalysis");
                phContentMA.Controls.Add(pa);
                break;
            case 4:
                var bo = Page.LoadControl("BackOrders");
                phContentMA.Controls.Add(bo);
                break;
        }
    }

    protected void cbMyAccount_SelectedIndexChanged(object sender, EventArgs e)
    {
        LoadStage(cbMyAccount.SelectedIndex);            
    }
}

父.ascx:

<%@ Control Language="c#" Codebehind="MyAccount.ascx.cs" Inherits="Controls.MyAccount"%>

Action: <asp:dropdownlist id="cbMyAccount" runat="server" EnableViewState="False" AutoPostBack="True" OnSelectedIndexChanged="cbMyAccount_SelectedIndexChanged" />

<asp:PlaceHolder id="phContentMA" runat="server"></asp:PlaceHolder>

有问题的子控件:

public class ProductAnalysis : BaseAuthControl
{
    protected Repeater rptrProducts;

    protected Literal ltStockCode;
    protected Literal ltStockDesc;
    protected Literal ltQtySold;
    protected Literal ltAmount;

    protected HyperLink lnkAddToCart;

    protected CheckBox chkMultiple;

    protected override void OnInit(EventArgs e)
    {
        base.OnInit(e);

        var saleStats = // results from the database;

        rptrProducts.DataSource = saleStats;
        rptrProducts.DataBind();
    }

    protected void rptrProducts_ItemDataBound(object sender, RepeaterItemEventArgs e)
    {            
        if (e.Item.ItemType != ListItemType.Item && e.Item.ItemType != ListItemType.AlternatingItem) return;

        var saleItem = e.Item.DataItem as TSaleStat;

        if (saleItem == null) return;

        var stockItem = GetItem(saleItem.StockCode);

        if (stockItem == null) return;

        if (CCUtils.AssignRepeaterControl(e, out ltStockCode, "ltStockCode"))
            ltStockCode.Text = stockItem.StockCode;

        if (CCUtils.AssignRepeaterControl(e, out ltStockDesc, "ltStockDesc"))
            ltStockDesc.Text = stockItem.ShortDesc;

        if (CCUtils.AssignRepeaterControl(e, out ltQtySold, "ltQtySold"))
            ltQtySold.Text = saleItem.QuantitySold.ToString(CultureInfo.InvariantCulture);

        if (CCUtils.AssignRepeaterControl(e, out ltAmount, "ltAmount"))
            ltAmount.Text = CCUtils.GetCurrencyPrice(Session, (decimal)saleItem.TotalPrice);

        if (CCUtils.AssignRepeaterControl(e, out lnkAddToCart, "lnkAddToCart"))            
            lnkAddToCart.NavigateUrl = stockItem.BuildBuyNowLink();

        if (CCUtils.AssignRepeaterControl(e, out lnkAddToCart, "lnkAddToCart"))
            lnkAddToCart.NavigateUrl = stockItem.BuildBuyNowLink();

        if (CCUtils.AssignRepeaterControl(e, out chkMultiple, "chkMultiple"))
        {                
            chkMultiple.Attributes.Add("value", stockItem.StockCode);
        }
    }

    protected void BtnClick(object sender, EventArgs e)
    {            
        var stockCodes = new List<string>();

        if (!rptrProducts.IsAssigned()) return;

        foreach (RepeaterItem repeaterItems in rptrProducts.Items)
        {                
            foreach (var childControl in repeaterItems.Controls)
            {
                var checkBox = childControl as CheckBox;

                if (checkBox == null) continue;

                if (checkBox.Checked) // always false here
                    stockCodes.Add(checkBox.Attributes["value"]);
            }
        }

        var test = stockCodes;
    }
}

还有子.ascx代码:

<%@ Control Language="c#"  Codebehind="ProductAnalysis.ascx.cs" Inherits="Controls.ProductAnalysis" %>

<div id="viewProductsPurchased">   
    <asp:Repeater runat="server" ID="rptrProducts" OnItemDataBound="rptrProducts_ItemDataBound" EnableViewState="True">
        <HeaderTemplate>
            <table>
                <thead>
                    <tr>
                        <th>Stock Code</th>
                        <th>Stock Description</th>
                        <th>Total Sold</th>
                        <th>Total Value</th>
                        <th colspan="2"><asp:Button runat="server" CssClass="uppercase" ID="Btn" OnClick="BtnClick" Text="Add selected to cart" UseSubmitBehavior="False" /></th> <!-- another postback with this button -->
                    </tr>
                </thead>
                <tbody>
        </HeaderTemplate>
        <ItemTemplate>
                    <tr>
                        <td>
                            <asp:Literal runat="server" ID="ltStockCode" />
                        </td>                        
                        <td>
                            <asp:Literal runat="server" ID="ltStockDesc" />
                        </td>
                        <td>
                            <asp:Literal runat="server" ID="ltQtySold" />
                        </td>
                        <td>
                            <asp:Literal runat="server" ID="ltAmount" />
                        </td>
                        <td>
                            <asp:HyperLink runat="server" Text="Add" CssClass="buttonlink" ID="lnkAddToCart" />
                        </td>
                        <td>
                            <asp:CheckBox runat="server" ID="chkMultiple" /> <!-- this checkbox never checked on postback -->
                        </td>
                    </tr>
        </ItemTemplate>
        <FooterTemplate>
                </tbody>
            </table>
        </FooterTemplate>
    </asp:Repeater>
</div>

我已经尝试将代码包装到!Page.IsPostBack:

if (!Page.IsPostBack) {
var saleStats = // results from the database;

rptrProducts.DataSource = saleStats;
rptrProducts.DataBind();
}

在这种情况下,由于下拉列表的回发,没有加载任何内容。

我愿意接受任何建议、修复或解决方法来解决这个问题 - 已经花费了太多时间。

附:抱歉代码膨胀,如果有任何缺少的结束标签,请忽略。

【问题讨论】:

  • 使用 ajax 和 web api 来防止回发。这样您就不必担心存储状态
  • @LiverpoolOwen 做出这样的改变为时已晚
  • LoadStage(3); 包裹在If (!IsPostback) { ... } 内。
  • @Prabhat 好地方,但不幸的是没有变化。还尝试将父控件包装到 UpdatePanel 中,希望它能以不同的方式处理回发,但也没有运气
  • 如果我设置EnableViewState="False",控件的值将不会在回发之间持续存在。删除此属性并再次检查。

标签: c# asp.net


【解决方案1】:

(From MSDN) ASP.NET 页面框架自动使用视图状态来持久化必须在回发之间保留的信息。此信息包括控件的任何非默认值。

视图状态是 ASP.NET 页面中的一个存储库,可以存储在回发期间必须保留的值。页面框架使用视图状态在回发之间保持控制设置。这会在回发之间保留值而不将它们存储在会话状态中

在您的情况下,将此属性设置为false,这些控件的值在回发期间丢失了。删除此属性将有助于确定下拉选择是否发生变化。

【讨论】:

  • 再次感谢@Prabhat
猜你喜欢
  • 2011-12-11
  • 1970-01-01
  • 2020-09-13
  • 2017-11-17
  • 2013-05-21
  • 2016-09-23
  • 2010-12-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多