Динамическое добавление контролов
Редкая функциональность может быть обеспечена одной-единственной статической страничкой. MultiView тоже не очень выручает, ибо все его составляющие собираются на страничку каждый постбэк и инициализируются. Поэтому в ASP2 существует всего два пути - множество разных страничек либо одна сложная страничка с динамическим добавлением контролов на нее (в зависимости от щелчков юзера по другим контролам).
Основная хитрость агрегирования функциональности в ASP2 заключается в том, что ДИНАМИЧЕСКОЕ ДОБАВЛЕНИЕ КОНТРОЛОВ МОЖНО ДЕЛАТЬ ТОЛЬКО В FORM_LOAD. Невыполнение этого условия ведет к незамедлительному появлению ран-таймового сообщения:
Этого сообщение если сильно исхитрится, то можно избежать, но добавленные не в Form_Load контролы все равно не будут иметь состояния, а такие контролы - бесмысленны. Если же добавлять контролы динамически именно в Form_load, то у них будет полная поддержка состония, включая даже встроенный пейджинг (а не только SelectedItem_Change).
Само по себе добавление контролов сложности не представляет и делается двумя равнозначными способами:
Dim x = Me.LoadControl("~/Control/ForumSubGroup.ascx")
P2.Controls.Add(X)
или
Dim X As New ASP.control_forumsubgroup_ascx
P2.Controls.Add(X)
второй способ дважды предпочтительнее, ибо позволяет ссылаться на свойства контрола не вот так
CType(X, ASP.control_forumsubgroup_ascx).SubGroup = Value(2)
а напрямую
X.SubGroup = Value(2)
причем делать это с подсказкой:
Чтобы получить такую подсказку, контролы надо зарегистрировать на страничке, проще всего их туда кинуть по Drag-and-Drop и потом удалить. Тогда на страничке самих контролов не будет, но останутся только их определения, причем без грамматических ошибок:
Но основная проблема ASP2-программирования в том, что согласно жизненному циклу странички, состояние контролов среда на этапе FORM_LOAD только заливает, иными словами события типа X.Selected произойдут ПОЗЖЕ. В тот момент, когда динамическое добавление других контролов (в соответствии с состоянием, выбранным в управляющем контроле) - уже делать ПОЗДНО. В этом случае - единственно возможный путь решения - выполнить PostBack с управляющего контрола на промежуточную страничку, на ней выставить состояние в SESSION (я делаю именно так) и выполнить Редирект на основную страничку. Может показаться, что это слишком длинный цикл обработки и возникает навязчивое желание сделать эти проходные странички просто Web-хандлерами ASHX, однако это не получится, ибо хандлер именно тем и отличается от странички, что на него движком ASP2 не накатывается состояние, следовательно наша цель выставить нужное состояние в SESSION для обработки его на главной страничке просто не будет достигнута, ибо SESSION в хандлере просто нет.
Таким образом на основной страничке уже на этапе LOAD будет известна необходимость динамической загрузки контролов.
На основной страничке есть несколько различных техник ветвления и определения необходимости дозагрузки контролов на страничку. Можно смотреть Request.Querystring, можно Me.PreviousPage, но я предпочитаю - State-машины:
Такие странички-пустышки я собираю в отдельную папочку LINK - все они имеют примерно вот-такой вид:
Таким образом я поступаю и с постбеками Комбешников и постбеками Буттонов и постбеками Меню. Единственное здесь - правильно сформировать параметры URL для проходной странички. В простейших случаях это может быть выполнено с помощью привязки.
Например, вот такие адреса переходов в элементе Menu
Формируются вот такой привязкой элементов меню к дереву:
Дополнительное приобретение в этом случае по сравнению с обычным Постбеком - то что наши странички вместо угрюмого javascropt:__doPostBack('MyControl','MyPage') приобрели нормальные адреса, что позволяет их индекировать в поисковых роботах.
|