【问题标题】:ASP.NET custom user control inside a repeater: Add item dynamically中继器内的 ASP.NET 自定义用户控件:动态添加项目
【发布时间】:2018-03-17 15:52:22
【问题描述】:

我有一个客户用户控件,AddressControl.ascx,它包含在转发器控件中。当我的页面第一次加载时,一切似乎都工作正常,我的转发器正在为 Page_Load 事件中填充的虚拟地址创建两个项目。但是,当我点击 Add Address 按钮时,添加了第三个中继器项目,但现在我所有其他中继器项目都是空的(即屏幕上的所有字段都变为空)。

在调试时,我注意到在第一次加载时,AddressControl 的 Page_Load 事件具有地址对象。但是,当我们点击Add Address按钮后来到Page_Load,地址对象为null。

*注意:添​​加地址按钮的目的是显示一组空控件,以允许用户输入新地址。

非常感谢任何帮助。

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();
    }
}

【问题讨论】:

    标签: c# asp.net user-controls repeater


    【解决方案1】:

    如果您希望控件在回发后保留值,则需要实现视图状态跟踪

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

    【讨论】:

      【解决方案2】:

      我想通了。

      这一切都与页面事件生命周期有关。如您所见,我试图访问 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 中的 Address 对象是使用 ViewState 实现的,则事件不会有帮助,因为在上面的第 2 步中,它将引用上一个 PostBack 中的旧对象。

      【讨论】:

        猜你喜欢
        • 2011-01-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-06-09
        • 1970-01-01
        • 2012-02-11
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多