maxp
maxp

Reputation: 25141

Confused over ViewState / IPostback with persisting textbox values

Scenario 1: I create a TextBox, Button, add them to the page, and Set the TextBox's value all in the Page's OnInit or OnLoad event.

When I do a postback / form post, via the Button click, whatever I had entered into the TextBox (from the browser) is persisted to the next postback / page load.

Scenario 2: I create a TextBox and Button and add them to the page on the OnInit event. I set the TextBox value on the OnLoad event,

When I do a postback /form post, via the Button click, whatever I had entered into the TextBox (from the browser) is not persisted, and instead the value I assigned during the OnLoad event is shown.

Can anyone explain what's happening here? At a guess I would say that ViewState tracking is only started for the TextBox in the event following it being added, or its being marked 'Dirty' as soon as it is assigned in the next event (OnLoad), but these really are guesses!

Upvotes: 2

Views: 1367

Answers (4)

Michael Liu
Michael Liu

Reputation: 55359

Let's start by clearing up a common misconception: The value of a TextBox is persisted across postbacks because the browser sends the value as part of the form data in each POST, not because the value is saved in view state. View state has nothing to do with the behavior you're seeing!

Here are the stages of the page life cycle that are relevant to this question:

  1. Raise the Init event.
  2. Load posted form data (first attempt).
  3. Raise the Load event.
  4. Load posted form data (second attempt).

Now let's walk through each of your scenarios and see what happens when the user changes the value of the text box and clicks the button.

Scenario 1a: Add controls and set the Text property in OnInit.

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. Raise the Init event. The TextBox is added to the page and its Text property is set to "Hello".
  2. Load posted form data (first attempt). The Text property is set to the value entered by the user.
  3. Raise the Load event. Nothing happens.
  4. Load posted form data (second attempt). Nothing happens because the first attempt to load the Text property succeeded.

Final result: The value entered by the user is persisted.

Scenario 1b: Add controls and set the Text property in OnLoad.

protected override void OnLoad(EventArgs e)
{
    this.placeHolder.Controls.Add(this.textBox);
    this.placeHolder.Controls.Add(this.button);
    this.textBox.Text = "Hello";
}
  1. Raise the Init event. Nothing happens.
  2. Load posted form data (first attempt). Nothing happens because the TextBox hasn't been added to the page yet.
  3. Raise the Load event. The TextBox is added to the page and its Text property is set to "Hello".
  4. Load posted form data (second attempt). The Text property is set to the value entered by the user.

Final result: The value entered by the user is persisted.

Scenario 2: Add controls in OnInit. Set the Text property in OnLoad.

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. Raise the Init event. The TextBox is added to the page.
  2. Load posted form data (first attempt). The Text property is set to the value entered by the user.
  3. Raise the Load event. The Text property is set to "Hello".
  4. Load posted form data (second attempt). Nothing happens because the first attempt to load the Text property succeeded.

Final result: The value entered by the user is overwritten.

Upvotes: 3

TheGeekYouNeed
TheGeekYouNeed

Reputation: 7539

A control's viewstate tracking is turned on at the end of the control's init event. Remember that control events occur before a page's.

PreInit is the event you should be adding dynamic controls in, however Init will work but you could see some inconsistent behavior. Load shouldn't be used -- for obvious reasons.

Always check !IsPostback when setting a control's initial values.

Upvotes: 1

Aghilas Yakoub
Aghilas Yakoub

Reputation: 28970

Load View State occur between Init and Load, after Init and before Lod

The load view state stage only happens when the page has been posted back. During this stage, the view state data that had been saved from the previous page visit is loaded and recursively populated into the control hierarchy of the Page. It is during this stage that the view state is validated.

If you want persist your data with viewstate, you must not re-bind your data for each post

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

And use viewstate to persist

Upvotes: 0

tranceporter
tranceporter

Reputation: 2261

ViewState tracking is turned on in the InitComplete event. So when you add a control on OnInit, it is not tracked by the viewstate, where as, when you add it on Page_Load, it is being tracked by the viewstate, and you can retrieve the persisted value of the textbox.

Upvotes: -1

Related Questions