Viewstate - 完全混乱。

时间:2009-11-10 13:36:48

标签: asp.net viewstate

这让我感到很困惑,有人可以解释一下吗?

标记:

<form id="form1" runat="server">
    <asp:TextBox runat="server" ID="txtTest" />
    <asp:PlaceHolder runat="server" ID="PlaceHolder1" />
    <asp:Button runat="server" Text="Click" />
</form>

代码背后:

protected void Page_Load(object sender, EventArgs e)
{
    txtTest.Text = "BBB";
    PlaceHolder1.Controls.Add(new TextBox() { Text = "AAA" });
}    

当我更改两个文本框中的文本,然后单击“单击”按钮时,txtTest中的文本将恢复为原始值“BBB”(在page_load中指定),但动态文本框保留我刚刚输入的值(而不是“AAA”)尽管与另一个“硬编码”文本框同时指定。

6 个答案:

答案 0 :(得分:3)

静态文本框只能使用!IsPostBack检查初始化一次。

if (!IsPostBack)
{
    txtTest.Text = "BBB";
}

动态文本框保留其值,因为在将Viewstate添加到PlaceHolder控件集合时会对其应用。

如果您这样做,修改后的值将会丢失:

TextBox txt = new TextBox();
PlaceHolder1.Controls.Add(txt);
txt.Text = "AAA";

修改: 正如Mike J所提到的,前面的代码示例是错误的。

  

Jeff Cyr的代码不起作用,因为   控制不会追赶   直到你退出Page_Load。

答案 1 :(得分:3)

在Page_Load事件中正在覆盖txtTest的值,因此您将看不到ViewState值。 ViewState值在PreLoad阶段加载。

动态控件的值接收ViewState值,因为您正在设置文本,然后将控件添加到页面。当控件添加到页面时,它将跟踪它的事件。在此追赶期间,该值将从ViewState加载,覆盖您的初始值。

Jeff Cyr的代码不起作用,因为在您退出Page_Load之前,控件不会进行追赶。如果你绑定到新的TextBox的Load事件并抛出几个Response.Writes,你可以看到这个。

protected void Page_Load(object sender, EventArgs e)
{
    txtTest.Text = "BBB";
    //PlaceHolder1.Controls.Add(new TextBox() { Text = "AAA" });
    TextBox txt = new TextBox();
    txt.Load += new EventHandler(txt_Load);
    PlaceHolder1.Controls.Add(txt);
    Response.Write("page load");
    txt.Text = "AAA";
}

void txt_Load(object sender, EventArgs e)
{
    Response.Write("textbox load");
}

答案 2 :(得分:1)

我认为您应该将用于设置文本的代码放在if(!IsPostBack)

protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack)
    {
        txtTest.Text = "BBB";
    }

PlaceHolder1.Controls.Add(new TextBox() { Text = "AAA" });
}

对于new TextBox()代码,Text属性的值在TextBox上设置,然后才会添加到Page中,因此它会保留用户输入的对文本的更改回发。

答案 3 :(得分:1)

除了来自o.k.w的回答。

从以下代码开始学习。

<form id="form1" runat="server">
    <div>
        <asp:Button ID="Button1" runat="server" Text="Button" OnClick="Button1_OnClick" />
    </div>
</form>

protected void Page_PreInit(object sender, EventArgs e)
{
    Response.Write("This is PreInit.... <br/>");
}

protected void Page_Init(object sender, EventArgs e)
{
    Response.Write("This is Init... <br/>");
}

protected void Page_InitComplete(object sender, EventArgs e)
{
    Response.Write("This is InitComplte... <br/>");
}

protected void Page_PreLoad(object sender, EventArgs e)
{
    Response.Write("This is PreLoad... <br/>");
}

protected void Page_Load(object sender, EventArgs e)
{
    Response.Write("This is Load... <br/>");

    Response.Write("IsPostback: " + IsPostBack + " <br/>");

}

protected void Page_LoadComplete(object sender, EventArgs e)
{
    Response.Write("This is LoadComplete... <br/>");
}

protected void Page_PreRender(object sender, EventArgs e)
{
    Response.Write("This is PreRender... <br/>");
}

protected void Page_RenderComplete(object sender, EventArgs e)
{
    Response.Write("This is RenderComplete... <br/>");
}

protected void Page_Unload(object sender, EventArgs e)
{
    //Response.Write("This is Unload... <br/>");
}

protected void Button1_OnClick(object sender, EventArgs e)
{
    Response.Write("This is Button1_OnClick.... <br/>");
}

答案 4 :(得分:0)

您需要在Page_Load之前添加新的TextBox控件(例如,在Page_Init中但不在之前)。

“静态”TextBox的默认值只需初始化一次(例如! IsPostbackPage_Load}。

看看Page Lifecycle

答案 5 :(得分:0)

我发现将ViewState添加到动态添加的文本框中有两个问题。

  1. 在将ViewState应用于动态控件之前,正在创建和更新控件。这将在Page_Load之后但在您点击按钮之前发生。这就是你的Text值被覆盖的原因。
  2. 要一致地发布ViewState,您需要为动态添加的控件分配一个不会更改的ID。否则,当页面获得更多动态控件时,您将看到ViewState不能按预期应用的时间。