ASP.Net中的持久动态控制

 //once clicked:  //when clicked again:   //and so on... 

有没有办法创建动态控件,即使在回发后仍然会持续存在? 换句话说,当用户点击按钮时,将生成一个新的文本框,当再次点击时,第一个将保留,而第二个将生成。 我怎么能用asp.net做到这一点? 我知道如果我可以在page_init事件中创建控件,那么它们将保持不变但我不知道是否可以在page_init发生之前处理按钮单击,因此必须有另一种方法。

是的,这是可能的。 使用纯ASP.NET(这看起来像你要求的)的一种方法是保持你添加的TextBox控件的计数(将该值存储在ViewState )并重新创建TextBox控件。 Page_Load事件。 当然,现在大多数人可能会使用Javascript或jQuery来处理这个任务客户端,但是我总结了一个快速示例来演示它如何与回发一起使用:

首页:

 <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="DynamicControls.aspx.cs" Inherits="MyAspnetApp.DynamicControls" EnableViewState="true" %>     

代码背后:

 using System; using System.Web.UI.WebControls; namespace MyAspnetApp { public partial class DynamicControls : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { //Recreate textbox controls if(Page.IsPostBack) { for (var i = 0; i < TextBoxCount; i++) AddTextBox(i); } } private int TextBoxCount { get { var count = ViewState["txtBoxCount"]; return (count == null) ? 0 : (int) count; } set { ViewState["txtBoxCount"] = value; } } private void AddTextBox(int index) { var txt = new TextBox {ID = string.Concat("txtDynamic", index)}; txt.Style.Add("display", "block"); phControls.Controls.Add(txt); } protected void btnAddTextBox_Click(object sender, EventArgs e) { AddTextBox(TextBoxCount); TextBoxCount++; } protected void btnWriteValues_Click(object sender, EventArgs e) { foreach(var control in phControls.Controls) { var textBox = control as TextBox; if (textBox == null) continue; Response.Write(string.Concat(textBox.Text, "
")); } } } }

由于您要在每个回发上重新创建控件,因此输入到文本框中的值将在每个回发中保留。 我添加了btnWriteValues_Click以快速演示如何从文本框中读取值。

编辑
我更新了示例以添加包含TextBox和Remove Button的Panel。 这里的技巧是删除按钮不会删除容器面板,它只是使它不可见。 这样做是为了使所有控件ID保持不变,因此输入的数据保留在每个TextBox中。 如果我们要完全删除TextBox,那么删除的TextBox之后的数据会在下一个回发中向下移动一个TextBox(只是为了更清楚地解释一下,如果我们有txt1,txt2和txt3,我们删除txt2,在下一个回发中,我们将创建两个文本框,txt1和txt2,并且txt3中的值将丢失)。

 public partial class DynamicControls : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { if (Page.IsPostBack) { for (var i = 0; i < TextBoxCount; i++) AddTextBox(i); } } protected void btnAddTextBox_Click(object sender, EventArgs e) { AddTextBox(TextBoxCount); TextBoxCount++; } protected void btnWriteValues_Click(object sender, EventArgs e) { foreach(var control in phControls.Controls) { var panel = control as Panel; if (panel == null || !panel.Visible) continue; foreach (var control2 in panel.Controls) { var textBox = control2 as TextBox; if (textBox == null) continue; Response.Write(string.Concat(textBox.Text, "
")); } } } private int TextBoxCount { get { var count = ViewState["txtBoxCount"]; return (count == null) ? 0 : (int) count; } set { ViewState["txtBoxCount"] = value; } } private void AddTextBox(int index) { var panel = new Panel(); panel.Controls.Add(new TextBox {ID = string.Concat("txtDynamic", index)}); var btn = new Button { Text="Remove" }; btn.Click += btnRemove_Click; panel.Controls.Add(btn); phControls.Controls.Add(panel); } private void btnRemove_Click(object sender, EventArgs e) { var btnRemove = sender as Button; if (btnRemove == null) return; btnRemove.Parent.Visible = false; } }

我阅读了Scott Mitchell的一篇文章,该文章解释了ViewState仅在post-back中保持更改的控制状态,而不是实际的控件本身。 我没有你的具体情况,但我正在处理的项目需要动态添加用户控件,我不得不在每次回发时添加它们。 在这种情况下,在Init中创建它们仍然很有用,这样它们就可以保留它们的状态。 这是链接: 了解ASP.NET视图状态 。 检查“查看状态和动态添加的控件”部分。

您可能必须跟踪要添加的所有控件(例如,在会话状态中)并在回发时重新创建它们。 我刚做了一个小测试,我在Session中保留了所有Textbox ID的List 。 在回发时,我重新创建所有文本框。