Захват событий из динамически добавленных пользовательских элементов управления ASP.NET

У меня есть веб-форма ASP.NET, к которой я добавляю переменные User Controls. У меня две проблемы:

  • Элементы управления пользователя добавляются в PlaceHolder в форме в первом событии PageLoad (я добавляю их только когда "(! this.IsPostback)", но затем, когда форма отправляется назад, элементы управления не отображаются Это нормально? Поскольку другие элементы управления в форме сохраняют свое состояние, я бы ожидал, что эти динамически добавленные остаются и в форме. Должен ли я добавлять их для каждой обратной передачи?

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

6 ответов

  • Да, вам нужно добавить их в каждую обратную передачу.
  • Да... элемент управления должен находиться в иерархии управления, прежде чем asp.net отправит событие (т.е. создаст динамические элементы управления как можно раньше на жизненном цикле страницы).


1) Вы должны добавить элементы управления в Pre-init (жизненный цикл страницы)

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


Я столкнулся с одной и той же проблемой и боролся через 5-6 часов. Я отправляю это, может быть, кто-то вроде меня может получить помощь.

1) Вы должны инициализировать свои элементы управления в событии Page.PreInit. (В моем случае мне пришлось добавить свои элементы управления в держатель места, поэтому я предварительно расширил PreInit, чтобы загрузить эти элементы управления, но вам не нужно это делать. Это зависит от вашего сценария.)

2) Вы должны привязать эти точные методы к своим элементам управления после их инициализации в своем событии Page.PreInit.

Вот мой пример кода:

protected override void OnPreInit(EventArgs e)
{
 // Loading controls...
 this.PrepareChildControlsDuringPreInit();
 // Getting ddl container from session and creating them...
 if (GetDDLSession().Count != 0)
 {
 foreach (DropDownList ddl in GetDDLSession())
 {
 ddl.SelectedIndexChanged += SelectedIndexChanged;
 phDropDowns.Controls.Add(ddl);
 }
 }
 base.OnPreInit(e);
}
public static void PrepareChildControlsDuringPreInit(this Page page)
{
 // Walk up the master page chain and tickle the getter on each one 
 MasterPage master = page.Master;
 while (master != null) master = master.Master;
}


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


  • Чтобы достичь этого, добавьте элементы управления на странице init вместо загрузки страницы. (повторно добавить в postback)
  • Вам нужно знать идентификатор добавленных кнопок, чтобы связать их с событием.


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

Protected Overrides Sub LoadViewState(ByVal savedState As Object)
 MyBase.LoadViewState(savedState)
 If IsPostBack Then
 CreateMyControls()
 End If
End Sub

licensed under cc by-sa 3.0 with attribution.