4

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

正如它在这篇文章中所说。

如果创建这些控件的标准在 Web 环境之外,例如数据库,则实现此行为没有问题。但是,如果我用来决定我必须创建多少个动态控件实际上是控件中的一个值,我该怎么办?

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

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

问题来了。因为我处于初始化阶段,所以我没有视图状态,所以我无法访问告诉我应该创建多少个动态复选框的文本框中的值。

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

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

感谢和抱歉这么长的帖子!

4

3 回答 3

1

第一件事 - 文本框值未从视图状态存储/检索,您无法从视图状态获取文本框值。谈到实际问题,这里是(imp)事件的顺序 init -> 加载视图状态 -> 绑定回发数据 -> 页面加载。只有在绑定回发数据事件(它实际上获取发布的数据并绑定到文本框控件)之后才能检索文本框值。在初始化中,唯一的选择是使用 Request.Form{"textboxid"] 来获取文本框值。

于 2013-03-26T14:54:30.383 回答
0

You are on the right track.

If you use TextBox, you do not need another ViewState to keep track of how many controls has been created, because TextBox control has its own ViewState already.

You can use either Page_Init or Page_Load to load control back.

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.";
        }
    }
}
于 2013-03-26T15:03:49.267 回答
0

当您使用背后的代码时,这是页面生命周期的常见悖论。例如,您将编辑 customerid 保存在 viewstate 中,但控件需要在 init 上绑定才能读取其发布的值。

现实生活中最好的解决方案是做绑定控件在回发时所做的事情,在页面加载事件中创建它们之后,显式调用所有控件实现的 IPostBackDataHandler 接口上的 LoadPostBackData。

您应该为 Controls 创建一个扩展方法并在需要时调用它: control.DataBind(); control.LoadPostedData(); // 扩展方法

于 2014-10-24T16:49:38.110 回答