【发布时间】: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",控件的值将不会在回发之间持续存在。删除此属性并再次检查。