在页面中保持一个值。在asp.net中的回发之间插入

时间:2013-03-26 14:20:17

标签: asp.net postback viewstate dynamic-controls

好的,我已经了解到为了在asp.net中保留动态(创建的)控件及其视图状态,我们必须(重新)在Page init事件中创建它们,因此它们已经存在于页面的控件层次结构中在加载视图状态之前。

正如在article中所说的那样。

如果创建这些控件的条件位于Web环境之外(例如数据库),则无法实现此行为。但是如果我用来决定我必须创建多少动态控件实际上是控件中的值,我该怎么办?

我尝试用一​​个例子来解释它,也许它更清楚:

假设我们有一个文本框和两个按钮。在文本框中,我写了我想要创建的动态控件的数量,例如4复选框。当我按下button1时,应该创建控件。没问题。然后我检查一些复选框并按下button2只是为了触发回发。现在我应该在页面init事件中重新创建控件,就像我们之前说过的那样,以便维护控件及其状态。

这就是问题。因为我在 init阶段我有没有viewstate 所以我无法访问文本框中的值,告诉我应该创建多少个动态复选框

我认为将值存储在会话对象中可以解决问题,但事实并非如此。会话对象也不可访问。

我在哪里可以保存从init事件中可以访问的值?

感谢并为这篇长篇文章感到抱歉!

3 个答案:

答案 0 :(得分:1)

首先 - 文本框值未从视图状态存储/检索,您无法从viewstate获取文本框值。 出现实际问题,这里是(imp)事件序列init - >加载视图状态 - >绑定回发数据 - >页面加载。您只能在绑定回发数据事件(实际上接收已发布的数据并绑定到文本框控件)后检索文本框值。 在init only选项中,使用Request.Form {“textboxid”]来获取文本框值。

答案 1 :(得分:0)

你走在正确的轨道上。

如果使用TextBox,则不需要另外一个ViewState来跟踪已创建的控件数,因为TextBox控件已经拥有自己的ViewState。

您可以使用Page_Init或Page_Load加载控制权。

enter image description here

<%@ 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。