好的,我已经了解到为了在asp.net中保留动态(创建的)控件及其视图状态,我们必须(重新)在Page init事件中创建它们,因此它们已经存在于页面的控件层次结构中在加载视图状态之前。
正如在article中所说的那样。
如果创建这些控件的条件位于Web环境之外(例如数据库),则无法实现此行为。但是如果我用来决定我必须创建多少动态控件实际上是控件中的值,我该怎么办?
我尝试用一个例子来解释它,也许它更清楚:
假设我们有一个文本框和两个按钮。在文本框中,我写了我想要创建的动态控件的数量,例如4复选框。当我按下button1时,应该创建控件。没问题。然后我检查一些复选框并按下button2只是为了触发回发。现在我应该在页面init事件中重新创建控件,就像我们之前说过的那样,以便维护控件及其状态。
这就是问题。因为我在 init阶段我有没有viewstate 所以我无法访问文本框中的值,告诉我应该创建多少个动态复选框
我认为将值存储在会话对象中可以解决问题,但事实并非如此。会话对象也不可访问。
我在哪里可以保存从init事件中可以访问的值?
感谢并为这篇长篇文章感到抱歉!
答案 0 :(得分:1)
首先 - 文本框值未从视图状态存储/检索,您无法从viewstate获取文本框值。 出现实际问题,这里是(imp)事件序列init - >加载视图状态 - >绑定回发数据 - >页面加载。您只能在绑定回发数据事件(实际上接收已发布的数据并绑定到文本框控件)后检索文本框值。 在init only选项中,使用Request.Form {“textboxid”]来获取文本框值。
答案 1 :(得分:0)
你走在正确的轨道上。
如果使用TextBox,则不需要另外一个ViewState来跟踪已创建的控件数,因为TextBox控件已经拥有自己的ViewState。
您可以使用Page_Init或Page_Load加载控制权。
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx.cs"
Inherits="WebApplication2010.WebForm1" %>
<!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">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:TextBox runat="server" ID="NumberTextBox" />
<asp:Button runat="server" ID="CreateControlButton"
OnClick="CreateControlButton_Click"
Text="Create Control" />
<br />
<asp:PlaceHolder runat="server" ID="PlaceHolder1"></asp:PlaceHolder>
</div>
</form>
</body>
</html>
using System;
using System.Web.UI;
namespace WebApplication2010
{
public partial class WebForm1 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (IsPostBack)
{
int ids;
if (Int32.TryParse(NumberTextBox.Text, out ids))
{
for (int i = 0; i < ids; i++)
{
Control ctrl = Page.LoadControl("WebUserControl.ascx");
ctrl.ID = i.ToString();
PlaceHolder1.Controls.Add(ctrl);
}
}
}
}
protected void CreateControlButton_Click(object sender, EventArgs e)
{
}
}
}
<%@ Control Language="C#" AutoEventWireup="true"
CodeBehind="WebUserControl.ascx.cs"
Inherits="WebApplication2010.WebUserControl" %>
<asp:CheckBox runat="server" ID="CheckBox1" />
<asp:Button runat="server" ID="Button1" OnClick="Button_Click"
Text="Post Back" />
<asp:Label runat="server" ID="Label1" />
<br />
using System;
namespace WebApplication2010
{
public partial class WebUserControl : System.Web.UI.UserControl
{
protected void Button_Click(object sender, EventArgs e)
{
Label1.Text = " This control was posted back.";
}
}
}
答案 2 :(得分:0)
当您使用代码后,这是页面生命周期的常见悖论。例如,您将编辑customerid保存在viewstate中,但控件需要在init上绑定才能读取其发布的数据。
最佳实际解决方案是在回发时执行绑定控件的操作,在IPostBackDataHandler接口上显式调用LoadPostBackData,所有控件在页面加载事件中创建它们后,在params中实现传递控件UniqueId和Request.Form。
您可以为Controls创建扩展方法并按需调用它: control.DataBind(); control.LoadPostedData(); //扩展方法
希望有人帮助。 问候, Panos.R。