中继器内的ASP.NET自定义用户控件:动态添加项目
问题描述:
我有一个客户用户控件AddressControl.ascx,它包含在中继器控件中。当我的页面第一次加载时,一切似乎都正常,我的转发器正在为Page_Load事件中填充的虚拟地址创建两个项目。但是,当我点击添加地址按钮时,会添加第3个转发器项目,但现在所有其他转发器项目都是空的(即屏幕上的所有字段都变空)。中继器内的ASP.NET自定义用户控件:动态添加项目
在调试时,我注意到在第一次加载时,AddressControl的Page_Load事件具有地址对象。但是,当我们点击添加地址按钮后,我们来到Page_Load时,地址对象为空。
*注意:添加地址按钮的目标是让一组空白控件显示为允许用户输入新地址。
任何帮助,非常感谢。
AddressControl.ascx
public partial class AddressControl : System.Web.UI.UserControl
{
public Address address { get; set; }
protected void Page_Load(object sender, EventArgs e)
{
if (address != null)
{
txtStreet1.Text = address.Address1;
txtStreet2.Text = address.Address2;
txtCity.Text = address.City;
cboRegion.SelectedIndex = 2;
txtPostalCode.Text = address.PostalCode;
}
}
}
Default.aspx的
<asp:Repeater ID="AddrRepeater" runat="server" OnItemDataBound="AddrRepeater_ItemDataBound">
<ItemTemplate>
<uc1:AddressControl runat="server" id="ctlAddress" />
</ItemTemplate>
</asp:Repeater>
<asp:Button ID="btnAdd" runat="server" text="Add Address" OnClick="btnAdd_Click" />
Default.aspx.cs
public partial class Default : System.Web.UI.Page
{
public List<Address> Addresses
{
get
{
var addresses = HttpContext.Current.Session["addressList"] as List<Address>;
if (addresses == null)
{
addresses = new List<Address>();
HttpContext.Current.Session["addressList"] = addresses;
}
return addresses;
}
set
{
HttpContext.Current.Session["addressList"] = value;
}
}
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
Addresses = new List<Address>()
{
new Address { Address1 = "123 Main St", Address2 = "", City = "New York", State = "NY", PostalCode = "10001" },
new Address { Address1 = "555 Fake St", Address2 = "", City = "New York", State = "CA", PostalCode = "91367" }
};
AddrRepeater.DataSource = Addresses;
AddrRepeater.DataBind();
}
}
protected void AddrRepeater_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
var address = e.Item.DataItem as Address;
var addrCtl = e.Item.FindControl("ctlAddress") as AddressControl;
addrCtl.address = address;
}
}
protected void btnAdd_Click(object sender, EventArgs e)
{
Address newAddress = new Address();
Addresses.Add(newAddress);
AddrRepeater.DataSource = Addresses;
AddrRepeater.DataBind();
}
}
答
你将需要实现视图状态轨迹如果你想让控件在回发后保留这些值
public Address address
{
get
{
object o = ViewState["address"];
return o == null ? null : (Address)o;
}
set {
ViewState["address"] = value;
}
}
答
我想通了。
这是关于Page Event Life Cycle的一切。如您所见,我试图访问Address对象并填充PageLoad事件中的文本框字段。 这是错误的。
这里是事件触发的顺序:
1. Default.aspx.cs - Page_Load
2. AddressControl.ascx.cs - Page_Load // Address object is still null here because it hasn't been assigned a value from the Default.aspx.cs's ItemDataBound event.
3. Default.aspx.cs - ItemDataBound // Address assigned here
4. AddressControl.ascx.cs - OnPreRender // Here the Address object is NOT null.
如果事件在AddressControl.ascx.cs我的地址对象是使用ViewState中实现的,它不会因为上述步骤2中的帮助下,它会引用上一个PostBack中的旧对象。