Динамически созданные элементы управления и жизненный цикл страницы ASP.NET - PullRequest
1 голос
/ 11 мая 2010

Я работаю над проектом ASP.NET, в котором подавляющее большинство форм генерируется динамически во время выполнения (определения форм хранятся в БД для возможности настройки). Поэтому я должен динамически создавать и добавлять свои элементы управления на страницу каждый раз, когда запускается OnLoad, независимо от IsPostBack. Это работает нормально, и .NET заботится об управлении ViewState для этих элементов управления.

protected override void OnLoad(EventArgs e)
{
    base.OnLoad(e);
    RenderDynamicControls()
}

private void RenderDynamicControls()
{
    //1. call service layer to retrieve form definition
    //2. create and add controls to page container
}

У меня есть новое требование, согласно которому, если пользователь нажимает на данную кнопку (эта кнопка создается во время разработки), страница должна быть перерисована немного другим способом. Таким образом, в дополнение к коду, выполняемому в OnLoad (т.е. RenderDynamicControls ()), у меня есть этот код:

protected void MyButton_Click(object sender, EventArgs e)
{
    RenderDynamicControlsALittleDifferently() 
}

private void RenderDynamicControlsALittleDifferently()
{
    //1. clear all controls from the page container added in RenderDynamicControls()

    //2. call service layer to retrieve form definition

    //3. create and add controls to page container
}

У меня вопрос: действительно ли это единственный способ добиться того, чего я добиваюсь? Кажется нехорошо эффективно дважды визуализировать форму, просто реагируя на нажатие кнопки. Из моего исследования я понял, что именно так работает жизненный цикл страницы в ASP.NET: именно, OnLoad должен запускаться при каждой обратной передаче перед вызовом дочерних событий. Тем не менее, стоит проконсультироваться с SO-сообществом, прежде чем пить kool-aid.

В связанной заметке, как только я завершу эту функцию, я планирую добавить UpdatePanel на страницу, чтобы выполнять обновления страницы через Ajax. Любой код / ​​совет, который облегчит этот переход, будет очень признателен.

1 Ответ

2 голосов
/ 11 мая 2010

От Дирка до Дирка: -)

Что вы имеете в виду под RenderDynamicControls? Создать и настроить элементы управления? Если это ваше намерение, не ASP.NET управляет вашим ViewState, а вы. Если вы заполняете элементы управления при каждой загрузке, вы всегда перезаписываете существующее ViewState!

Если вы хотите использовать ViewState, создайте свои элементы управления в событии init страниц и заполните их в событии load, но только если запрос не является обратной передачей. Это необходимо, потому что ASP.NET воссоздает ViewState между init и load. И это также причина двух «циклов рендеринга», которые вы описываете. Вам необходим первый цикл создания элемента управления, поскольку ASP.NET не может восстановить ViewState без правильного набора элементов управления, а ASP.NET не может правильно реагировать на ваш ответ без него.

Назад к вашему коду: В общем случае ваш RenderDynamicControlsALittleDifferently не будет работать - потому что вы создаете свои элементы управления слишком поздно в жизненном цикле страниц, и вы повредите ViewState, вставив новые объекты в коллекцию элементов управления. В аналогичной ситуации я решил эту проблему, перенаправив страницу на себя (Response.Redirect). В этом случае RenderDynamicControls выполнит эту работу, основываясь на «немного другой ситуации» после изменения вашего внутреннего состояния.

...