为啥我动态添加的控件在回发后会丢失它们的值?
Posted
技术标签:
【中文标题】为啥我动态添加的控件在回发后会丢失它们的值?【英文标题】:Why do my dynamically added controls loose their values after Postback?为什么我动态添加的控件在回发后会丢失它们的值? 【发布时间】:2013-01-10 20:46:38 【问题描述】:为了问我的问题,我创建了一个 aspx
文件,其中包含一个 Button
和一个带有 SqlDataSource 的 DataList
:
<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 接收数据的每个控件都应该在 Init 或 Load 事件处理程序中实例化,因为 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 在回发后失去样式
Error-ASP.NET:由于未能找到 id 为“FileUpload1$gvFiles$ctl02$lnkBtnRemoveFile”的控件或在回发后将同一 ID 分配给另一个控件,导致发生错误。