ASP.NET - принудительно запускать дочерние / контейнерные события перед родительской нагрузкой? - PullRequest
7 голосов
/ 12 мая 2010

Я работаю над приложением типа анкеты, в котором вопросы хранятся в базе данных. Поэтому я создаю свои элементы управления динамически на каждом Page.OnLoad. Это работает как чудо, и ViewState сохраняется между постбэками, потому что я гарантирую, что мои динамические элементы управления всегда имеют один и тот же сгенерированный Control.ID.

В дополнение к пользовательскому элементу управления, который динамически заполняет вопросы, моя страница вопросника также содержит раздел «Статус» (также инкапсулированный пользовательским элементом управления), который представляет состояние вопросника (варианты «Завершено», «Запущено»). или «В процессе»). Если пользователь меняет статус анкеты (то есть с «Выполняется» на «Завершено»), мне необходимо выполнить обратную передачу на сервер, поскольку содержимое динамической части анкеты зависит от выбранного статуса.

Некоторые вопросы всегда присутствуют независимо от статуса, а другие могут не присутствовать вообще для выбранного статуса. Дело в том, что, когда статус меняется, я должен вернуться на страницу и задать правильный набор вопросов. Кроме того, мне нужно сохранить любые введенные пользователем значения для тех вопросов, которые «всегда доступны».

Однако из-за жизненного цикла страницы в ASP.NET OnLoad пользовательского элемента управления «Статус», который содержит правильный статус, необходимый для загрузки нужных вопросов из БД, не выполняется до тех пор, пока не будут выполнены «динамические вопросы». 'пользовательский элемент управления уже заполнен (с неправильными / устаревшими значениями).

Чтобы обойти это, я поднимаю событие с моего пользовательского элемента управления «Статус» на главную страницу, чтобы указать, что Статус изменился. Затем на главной странице возникает событие в пользовательском элементе управления «динамические вопросы». Поскольку к тому времени, когда это событие всплывает, пользовательский элемент управления «динамические вопросы» уже загрузил «неправильные» вопросы из БД, он сначала вызывает Controls.Clear. Затем он с радостью использует новый статус для запроса «правильных» вопросов к базе данных и выполняет Control.Add () для каждого. К вашему сведению, Control.IDs одинаковы для всех постбэков.

Это решение работает ... Сорта. Правильный набор вопросов для выбранного статуса будет оказан; однако ViewState теряется для этих «всегда доступных» вопросов. Я предполагаю, что это потому, что пользовательский элемент управления «динамические вопросы» вызывает Controls.Clear при ответе на событие изменения статуса. Это должно как-то уничтожить связь между ViewState и моими динамическими элементами управления, даже если Control.ID совпадают.

Это кажется таким распространенным требованием, я практически уверен, что есть лучший, более чистый и менее подверженный ошибкам подход для достижения этой цели. В случае, если это не совсем очевидно, я не смог получить жизненный цикл страницы ASP.NET, несмотря на работу с ним в течение последнего года. Любая помощь очень ценится!

Ответы [ 4 ]

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

Однако из-за жизненного цикла страницы в ASP.NET, пользовательский элемент управления «Статус» OnLoad, который содержит правильный статус нужен для загрузки права вопросы из БД, не получается выполняется до "динамического пользовательский контроль вопросов уже заселено (с неправильным / несвежим значения).

Если вам известен идентификатор клиента базового элемента управления статусом, вы можете получить опубликованное значение в любой точке жизненного цикла страницы, обойдя веб-формы и получив прямой доступ к данным опубликованной формы:

// where 'selectedStatus' is the id of the html <input> control the user clicks
string statusString = Request.Form["selectedStatus"];
0 голосов
/ 13 мая 2010

Я гарантирую, что мои динамические элементы управления всегда одинаково генерируется Control.ID

ViewState сделаны независимо от идентификатора элемента управления. Если вы хотите обработать событие OnClick внутри вашего динамического элемента управления с введенными пользовательскими данными, вы должны восстановить структуру иерархии элементов управления до события RaisPostBackEvent, которое сработало сразу после Page_load.

Если вы хотите сохранить свои динамические элементы управления с тем же состоянием в другой позиции на своей странице, или вы хотите иметь доступ к элементам управления после создания других динамических элементов управления , вам необходимо сохранить иерархию элементов управления .

Так! Создайте свою первую часть динамических элементов управления в одном контейнере и создайте элементы управления при обратной передаче в другом контейнере.

Например, при запросе страницы вы отображаете:

< asp:placeholder id="iHaveToBeDuringAllRequests1" >
  First dynamic cintrols
< /asp:placeholder >
< asp:placeholder id="iHaveToBeDuringAllRequests2" >
  Empty on first request 
< /asp:placeholder >

В PostBack вы отображаете:

< asp:placeholder id="iHaveToBeDuringAllRequests1" >
  First dynamic cintrols(you can clear or do not load these controls if you don't need it)
< /asp:placeholder >
< asp:placeholder id="iHaveToBeDuringAllRequests2" >
  Second dynamic controls load here
< /asp:placeholder >

И последний совет:

Я гарантирую, что мои динамические элементы управления всегда одинаково генерируется Control.ID

Вам необходимо убедиться в этом для корректного запуска RaisPostBackEvent (OnClick и т. Д.) С помощью динамических элементов управления (вместо заполнителя можно использовать контейнер INamingContainer).

0 голосов
/ 17 мая 2010

Хмм - жизненный цикл страницы ASP.NET; один из моих любимых:)

Полагаю, это потому, что вызовы управления пользователями «динамические вопросы» Controls.Clear при ответе на событие изменило статус. Это должно каким-то образом убить связь между ViewState и мои динамические элементы управления, хотя Control.IDs последовательны.

Похоже, что это воссоздает все из состояния просмотра (включая вопросы "всегда включен"), а затем бросает его в корзину. После это элементы управления воссоздаются (без какого-либо состояния просмотра, потому что восстановление его уже выполнено). Так что да, я тоже думаю, что Controls.Clear является причиной вашего потерянного состояния просмотра.

Это, вероятно, не однострочник для решения. Я мог бы представить разные подходы.

Однако из-за жизненного цикла страницы в ASP.NET, пользовательский элемент управления «Статус» OnLoad, который содержит правильный статус нужен для загрузки права вопросы из БД, не получается выполняется до "динамического пользовательский контроль вопросов уже заселено (с неправильным / несвежим значения).

Что вы подразумеваете под "OnLoad содержит правильный статус"? Я бы сказал, что должна быть возможность получить «текущий выбор» из элемента управления состоянием во время динамического вопроса «привязка данных» (если у вас есть что-то подобное в вашем элементе управления динамическими вопросами). Причина, по которой я / думаю, заключается в том, что «связывание данных» (в родительском элементе) происходит после пункта 3, упомянутого в статье « Жизненный цикл страницы ASP.NET », представленной ниже , Так что, если ваш динамический контроль вопросов знает о статусе, который он должен соблюдать, он должен быть в состоянии получить его. Если это не работает, я бы сначала проверил, находится ли проблема в контроле состояния. Если ваш динамический контроль вопросов не знает ни о каком статусе, это, очевидно, не сработает.

Другой подход заключается в том, чтобы ваш динамический элемент управления вопросами удалял не всех своих детей (Controls.Clear), а только те, которые больше не нужны. Вы можете (и я думаю, вы должны) сделать это в PreRender. Таким образом, может быть полезно иметь средство для управления динамическими вопросами, чтобы отличать «всегда активные» вопросы от других. Затем вы можете придерживаться своей текущей тактики и события.

Если вы хотите глубже изучить жизненный цикл страницы ASP.NET и просмотреть состояние и еще не знаете их, эти две ссылки могут предоставить ценную информацию.

Жизненный цикл страницы ASP.NET и TRULY Понимание ViewState .

Если это не очевидно, я не удалось взломать ASP.NET жизненный цикл страницы, несмотря на работу с это за последний год.

Дайте мне знать, если вы найдете кого-то, кто имеет:)

0 голосов
/ 12 мая 2010

Вы можете изменить его, чтобы просто загрузить элементы управления (без определения какого-либо зависящего от состояния материала) в Page_Load и переместить визуализацию элементов управления, зависящую от состояния, в Page_PreRender.

Динамический пользовательский элемент управления может считывать данные из базы данных в своем событии PreRender (или событии DataBind), если пользовательский элемент управления отвечает за то, что загружать.

Мне кажется, проблема в том, что пользовательские элементы управления пытаются прочитать состояние до того, как все элементы управления будут загружены и состояние представления будет загружено. Откладывая отображение, зависящее от состояния, до события более поздней страницы, вы убедитесь, что оно основано на правильном статусе.

...