Viewstate - полная путаница. - PullRequest
       20

Viewstate - полная путаница.

2 голосов
/ 10 ноября 2009

Это меня совершенно озадачило, кто-нибудь может объяснить это?

Markup:

<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 ]

3 голосов
/ 10 ноября 2009

Значение txtTest перезаписывается в вашем событии Page_Load, поэтому вы не увидите значение ViewState. Значение ViewState загружается на этапе предварительной загрузки.

Значение для динамического элемента управления получает значение ViewState, поскольку вы задаете текст, а затем добавляете элемент управления на страницу. Когда элемент управления добавляется на страницу, он будет воспроизводить события. Во время этого захвата значение загружается из ViewState, перезаписывая ваше начальное значение.

Код Джеффа Кира не работает, потому что элемент управления не воспроизводится, пока вы не выйдете из Page_Load. Это можно увидеть, если вы подключитесь к событию Load нового TextBox и добавите пару 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");
}
3 голосов
/ 10 ноября 2009

Статическое текстовое поле должно быть инициализировано только один раз с проверкой! IsPostBack.

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

Динамическое текстовое поле сохраняет свое значение, поскольку Viewstate применяется к нему при добавлении в коллекцию элементов управления PlaceHolder.

Если вы сделали это вместо этого, измененное значение будет потеряно:

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

Редактировать : Как упоминал Майк Дж, предыдущий пример кода неверен.

Код Джеффа Сира не работает, потому что управление не играет в догонялки пока вы не выйдете из Page_Load.

1 голос
/ 10 ноября 2009

в дополнение к ответу от 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/>");
}
1 голос
/ 10 ноября 2009

Я думаю, что вы должны поместить код, который устанавливает текст внутри 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 до его добавления на страницу, и поэтому оно сохраняет введенные пользователем изменения в тексте при обратной передаче.

0 голосов
/ 10 ноября 2009

Я вижу две проблемы с получением ViewState в динамически добавляемом текстовом поле.

  1. Элемент управления создается и обновляется до применения ViewState к динамическим элементам управления. Это произойдет после Page_Load, но до события нажатия кнопки. Вот почему ваше текстовое значение перезаписывается.
  2. Чтобы ViewState был опубликован последовательно, необходимо назначить идентификатор динамически добавляемому элементу управления, который не изменяется. В противном случае, когда страница получит больше динамических элементов управления, вы увидите моменты, когда ViewState не будет применяться, как вы ожидаете.
0 голосов
/ 10 ноября 2009

Необходимо добавить новый элемент управления TextBox перед Page_Load (например, внутри Page_Init, но не раньше).

Значение по умолчанию для «статического» TextBox необходимо инициализировать только один раз (например, в пределах ! IsPostback) из Page_Load.

Взгляните на Page Lifecycle .

...