ASP.Net中的持久动态控件
本文关键字:动态控件 Net ASP | 更新日期: 2023-09-27 17:53:22
<asp:Button onclick="Some_event" Text="Add TextBox" ID="id1" runat="server" />
//once clicked:
<asp:TextBox ID="txt1" ......></asp:TextBox>
//when clicked again:
<asp:TextBox ID="txt1" ......></asp:TextBox>
<asp:TextBox ID="txt2" ......></asp:TextBox>
//and so on...
是否有一种方法可以创建动态控件,即使在回发后也会持续存在?换句话说,当用户单击按钮时,将生成一个新的文本框,当再次单击时,第一个文本框将保持不变,而第二个文本框将生成。我如何使用asp.net做到这一点?我知道,如果我可以在page_init事件中创建控件,那么它们将持续存在,但我不知道是否有可能在page_init发生之前处理按钮单击,因此必须有另一种方式。
是的,这是可能的。一种方法是使用纯ASP。NET(这似乎是您所要求的)将保留您添加的TextBox
控件的计数(将该值存储在ViewState
中),并在Page_Load
事件中重新创建TextBox
控件。当然,现在大多数人可能会使用Javascript或jQuery来处理这个客户端任务,但是我提供了一个快速示例来演示它是如何处理回发的:
:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="DynamicControls.aspx.cs" Inherits="MyAspnetApp.DynamicControls" EnableViewState="true" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server"></head>
<body>
<form id="form1" runat="server">
<div>
<asp:Button ID="btnAddTextBox" runat="server" Text="Add" OnClick="btnAddTextBox_Click" />
<asp:Button ID="btnWriteValues" runat="server" Text="Write" OnClick="btnWriteValues_Click" />
<asp:PlaceHolder ID="phControls" runat="server" />
</div>
</form>
</body>
</html>
背后的代码:
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, "<br />"));
}
}
}
}
由于要在每次回发上重新创建控件,因此输入到文本框中的值将在每次回发中持久化。我添加了btnWriteValues_Click
来快速演示如何从文本框中读取值。
编辑
我更新了这个例子,添加了一个包含TextBox和Remove Button的Panel。这里的技巧是,删除按钮不删除容器面板,它只是使它不可见。这样做是为了使所有控件id保持不变,因此输入的数据保留在每个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, "<br />"));
}
}
}
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在回发过程中只保留更改后的控件状态,而不是实际控件本身。我没有你的确切情况,但我正在工作的一个项目需要动态添加用户控件,我不得不在每次回发时添加它们。在这种情况下,在Init中创建它们仍然是有用的,这样它们就可以保持它们的状态。这里是链接:了解ASP。. NET视图状态。查看"视图状态和动态添加的控件"一节。
您可能必须跟踪您正在添加的所有控件(例如在会话状态中),并在发回时重新创建它们。我只是做了一个小测试,我在会话中保持所有文本框id的List<string>
。在回发时,我重新创建了所有的文本框。