为什么我的动态添加控件在Postback后会松开它们的值?

时间:2013-01-27 10:13:38

标签: asp.net event-handling postback viewstate servercontrols

要问我的问题,我创建了一个aspx文件,其中包含ButtonDataList以及 SqlDataSource

    <asp:Button ID="Button1" runat="server" Text="Button" onclick="Button1_Click" />

    <asp:DataList ID="DataList1" runat="server" DataKeyField="a" 
    DataSourceID="SqlDataSource1" >
        <ItemTemplate>
            a:
            <asp:Label ID="aLabel" runat="server" Text='<%# Eval("a") %>' />
            <br />
            b:
            <asp:Label ID="bLabel" runat="server" Text='<%# Eval("b") %>' />
            <br />
        </ItemTemplate>
    </asp:DataList>

<asp:SqlDataSource ID="SqlDataSource1" runat="server" 
    ConnectionString="<%$ ConnectionStrings:probaConnectionString %>" 
    SelectCommand="SELECT [a], [b] FROM [PROBA_TABLE]"></asp:SqlDataSource>

在我的代码中,我将TextBoxes添加到DataList的Items中。我在Page_Load中为每个Item添加了一个TextBox,在Button中添加了另一个TextBox,同时点击了eventhandler

    public partial class _Default : System.Web.UI.Page
    {   
        protected void Page_Load(object sender, EventArgs e)
        {
            if (IsPostBack)
            {
                foreach (DataListItem item in DataList1.Items)
                {
                    item.Controls.Add(new TextBox());
                }
            }
        }

        protected void Button1_Click(object sender, EventArgs e)
        {
            foreach (DataListItem item in DataList1.Items)
            {
                item.Controls.Add(new TextBox());
            }
        }

    }
}

除了一件事,这个工作正常。当我单击Button时,在Page_Load中创建的TextBox会保留其Text值,但在Button1_Click中创建的TextBox会丢失其Text值。我真正的问题比这更复杂,但我认为解决这个问题对我有很大帮助。

My site after postback

2 个答案:

答案 0 :(得分:3)

应该从页面ViewState接收数据的每个控件都应该在 Init 加载事件处理程序中实例化,因为ViewState会持久保存到控件之前点击,更改< / strong>和其他控制事件(检测到ViewState更改时会触发这些事件,因此必须在 Click 事件被触发之前读取ViewState。)

所以这个过程应该是这样的:

  1. OnInit (创建静态控件)
  2. 从ViewState
  3. 反序列化静态控件内容
  4. OnLoad (创建动态控件,在您的案例中,您在上一次回发中创建的文本框)
  5. 从ViewState
  6. 反序列化动态控件内容
  7. 点击,更改,根据检测到的比较POST数据和ViewState数据的变化触发其他事件
  8. <强>建议:

    您可以使用隐藏字段来保存其他状态信息,然后在OnLoad中,您可以读取该信息以重新创建动态创建的控件。

    此外,您应该明确设置文本框的ID属性,以便可以正确地保留值,不依赖于ASP.Net。

答案 1 :(得分:0)

默认情况下,http是无状态的,这意味着在处理完请求后,服务器不会保留请求的数据或信息 但是当出现错误时,表格中的值需要在特殊情况下保留 假设你填写一个长格式然后将其发回服务器只是为了得到一条错误消息,所有填满的值都消失了。不会那么烦人

所以asp.net在后台做了什么,它在页面中隐藏了一个字符串,其中包含有关所有服务器控件及其ID的信息。 因此,当您发布表单时,会创建Page class并在特定控件中回发和绑定值,因为Page class正在每个请求中创建pageLoad运行事件并在PageLoad中创建的控件然后将与其ID相对应的当前值放入其中。与在按钮单击上创建的控件不同,直到button_click事件运行该视图状态已被解除分类并且值已填入其中