为啥我动态添加的控件在回发后会丢失它们的值?

Posted

技术标签:

【中文标题】为啥我动态添加的控件在回发后会丢失它们的值?【英文标题】:Why do my dynamically added controls loose their values after Postback?为什么我动态添加的控件在回发后会丢失它们的值? 【发布时间】:2013-01-10 20:46:38 【问题描述】:

为了问我的问题,我创建了一个 aspx 文件,其中包含一个 Button 和一个带有 SqlDataSourceDataList

    <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 的项目中。我在 Page_Load 中为每个 Item 添加一个 TextBox,并在 Button Click eventhandler 中添加另一个 TextBox。

    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 中创建的 TextBoxes 保留其 Text 值,但在 Button1_Click 中创建的 TextBoxes 会丢失它们的 Text 值。我真正的问题比这更复杂,但我认为解决这个问题对我有很大帮助。

【问题讨论】:

【参考方案1】:

应该从页面 ViewState 接收数据的每个控件都应该在 InitLoad 事件处理程序中实例化,因为 ViewState 被持久化到控件 BEFORE Click, Change 和其他控件事件(这些事件在检测到 ViewState 更改时触发,因此必须在触发 Click 事件之前读取 ViewState)。

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

    OnInit(创建静态控件) 静态控件内容从 ViewState 反序列化 OnLoad(创建动态控件,在您的情况下是您在上次回发中创建的文本框) 动态控件内容从 ViewState 反序列化 Click、Change 和其他事件会根据检测到的比较 POST 数据和 ViewState 数据的变化触发

建议:

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

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

【讨论】:

@jannagy02 如果回复有帮助并且正确,请接受。用户输入使该网站正常工作。【参考方案2】:

http 默认是无状态的,这意味着在处理您的请求后,服务器不会保留请求的数据或信息 但是在特殊情况下,当出现错误时,表单中的值需要保留假设您填写了一个长表单,然后将其发送回服务器,只是为了得到一条错误消息和所有填充的值消失了。会不会很烦人 所以 asp.net 在幕后做了什么,它在页面中隐藏了一个字符串,其中包含有关所有服务器控件及其 id 的信息 因此,当您回发表单时,会创建 Page class,并在特定控件中回发并绑定值,因为在每个请求中都会创建 Page class,因此会运行 pageLoad 事件并创建控件然后在 PageLoad 中将与其 id 对应的当前值放入其中 与按钮单击上创建的控件不同 直到运行 button_click 事件,该事件已被反序列化并填充了值他们

【讨论】:

以上是关于为啥我动态添加的控件在回发后会丢失它们的值?的主要内容,如果未能解决你的问题,请参考以下文章

RadDatePicker 和 RadTimePicker 在回发后失去样式

Eval 方法在回发后不保存结果

更新面板内的jquery datepicker在回发后消失

在回发后重新选择

Error-ASP.NET:由于未能找到 id 为“FileUpload1$gvFiles$ctl02$lnkBtnRemoveFile”的控件或在回发后将同一 ID 分配给另一个控件,导致发生错误。

GridView 在回发或 onselectedindexchanged 后丢失数据表页眉和页脚