2017-10-05 71 views
0

我有一个客户用户控件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(); 
    } 
} 

回答

0

你将需要实现视图状态轨迹如果你想让控件在回发后保留这些值

public Address address 
    { 
     get 
     { 
      object o = ViewState["address"]; 
      return o == null ? null : (Address)o; 
     } 
     set { 
      ViewState["address"] = value; 
     } 
    } 
0

我想通了。

这是关于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中的旧对象。

相关问题