2

场景 1: 我创建一个TextBox, Button,将它们添加到页面中,并将TextBox' 的值全部设置在Page'OnInitOnLoad事件中。

当我通过点击进行回发/表单发布时,我(从浏览器)Button输入的任何内容都会保留到下一个回发/页面加载。TextBox

场景 2: 我创建了一个TextBox并将Button它们添加到OnInit事件的页面中。我设置了事件的TextBox值,OnLoad

当我通过Button单击进行回发/表单发布时,我(从浏览器)输入的任何内容TextBox都不会保留,而是显示我在OnLoad事件期间分配的值。

谁能解释这里发生了什么?猜测一下,我会说ViewState跟踪仅TextBox在事件被添加后开始,或者在下一个事件(OnLoad

4

4 回答 4

3

让我们首先澄清一个常见的误解:a 的值TextBox在回发中保持不变,因为浏览器在每个 POST 中将值作为表单数据的一部分发送,而不是因为值保存在视图状态中。视图状态与您看到的行为无关!

以下是与此问题相关的页面生命周期阶段:

  1. 引发Init事件。
  2. 加载已发布的表单数据(第一次尝试)。
  3. 引发Load事件。
  4. 加载已发布的表单数据(第二次尝试)。

现在让我们遍历每个场景,看看当用户更改文本框的值并单击按钮时会发生什么。

场景 1a:在 OnInit 中添加控件并设置 Text 属性。

private TextBox textBox = new TextBox { ID = "textBox" };
private Button button = new Button { ID = "submitButton", Text = "Submit" };

protected override void OnInit(EventArgs e)
{
    this.placeHolder.Controls.Add(this.textBox);
    this.placeHolder.Controls.Add(this.button);
    this.textBox.Text = "Hello";
}
  1. 引发Init事件。TextBox添加到页面并且其Text属性设置为“Hello”。
  2. 加载已发布的表单数据(第一次尝试)。Text属性设置为用户输入的值。
  3. 引发Load事件。什么都没发生。
  4. 加载已发布的表单数据(第二次尝试)。没有任何反应,因为第一次加载Text属性的尝试成功。

最终结果:用户输入的值被持久化。

场景 1b:在 OnLoad 中添加控件并设置 Text 属性。

protected override void OnLoad(EventArgs e)
{
    this.placeHolder.Controls.Add(this.textBox);
    this.placeHolder.Controls.Add(this.button);
    this.textBox.Text = "Hello";
}
  1. 引发Init事件。什么都没发生。
  2. 加载已发布的表单数据(第一次尝试)。没有任何反应,因为TextBox尚未添加到页面中。
  3. 引发Load事件。TextBox添加到页面并且其Text属性设置为“Hello”。
  4. 加载已发布的表单数据(第二次尝试)。Text属性设置为用户输入的值。

最终结果:用户输入的值被持久化。

场景 2:在 OnInit 中添加控件。在 OnLoad 中设置 Text 属性。

protected override void OnInit(EventArgs e)
{
    this.placeHolder.Controls.Add(this.textBox);
    this.placeHolder.Controls.Add(this.button);
}

protected override void OnLoad(EventArgs e)
{
    this.textBox.Text = "Hello";
}
  1. 引发Init事件。TextBox添加到页面。
  2. 加载已发布的表单数据(第一次尝试)。Text属性设置为用户输入的值。
  3. 引发Load事件。Text属性设置为“你好”。
  4. 加载已发布的表单数据(第二次尝试)。没有任何反应,因为第一次加载Text属性的尝试成功。

最终结果:用户输入的值被覆盖。

于 2012-08-31T17:50:06.737 回答
1

控件的视图状态跟踪在控件的 init 事件结束时打开。请记住,控制事件发生在页面之前。

PreInit 是您应该在其中添加动态控件的事件,但是 Init 会起作用,但您可能会看到一些不一致的行为。不应该使用负载——原因很明显。

设置控件的初始值时始终检查 !IsPostback。

于 2012-08-31T17:05:35.770 回答
0

加载视图状态发生在 Init 和 Load 之间,在 Init 之后和 Lod 之前

加载视图状态阶段仅在页面回发时发生。在这个阶段,从上一次页面访问中保存的视图状态数据被加载并递归地填充到页面的控制层次结构中。正是在这个阶段验证了视图状态。

如果你想用视图状态持久化你的数据,你不能为每个帖子重新绑定你的数据

If(! IsPostBack)
{
   //Bind here your textbox
}

并使用 viewstate 来持久化

于 2012-08-31T17:04:53.303 回答
-1

ViewState 跟踪在 InitComplete 事件中打开。因此,当您在 OnInit 上添加控件时,它不会被视图状态跟踪,而当您在 Page_Load 上添加它时,它会被视图状态跟踪,并且您可以检索文本框的持久值。

于 2012-08-31T16:28:28.460 回答