Viewstate и элементы управления в ASP.NET - PullRequest
8 голосов
/ 01 февраля 2012

Несколько дней назад я отправил вопрос о viewstate, и после выполнения некоторых тестов я пришел к некоторым выводам / результатам. На основании этих результатов у меня есть несколько вопросов о том, как кто-то будет делать определенные вещи.

Вот результаты моих тестов, которые я провел:

  1. Если usercontrolA загружен из OnInit страницы, его состояние просмотра будет доступно в OnLoad. Все остальные элементы управления, которые usercontrolA загружает из его OnInit, будут иметь готовое состояние просмотра в их OnLoad.
  2. Если usercontrolA загружен из OnLoad страницы, его состояние просмотра будет доступно в OnPreRender. Для всех других элементов управления, которые usercontrolA загружает из его OnLoad, их состояние просмотра будет доступно в их OnPreRender.
  3. Если usercontrolA загружен из события (Пример: нажатие кнопки. События начинаются после OnLoad и до OnPreRender) страницы, его состояние просмотра будет недоступно. Все остальные элементы управления, которые загружает usercontrolA, не будут иметь своего состояния просмотра.

Таким образом, в идеальном мире вы всегда загружали бы все элементы управления, используя ситуацию # 1, чтобы их представление состояния было доступно на их OnLoad. К сожалению, когда вам нужно загрузить элемент управления нажатием кнопки или из OnLoad, нет ли способа для элемента управления получить его представление до OnPreRender stage?

Я прочитал кучу статей о viewstate и подумал, что понял это, но работая над моим текущим приложением, которое загружает usercontrols, который загружает другие usercontrols, мне очень трудно получить viewstate на своем листе (последний в цепочке) usercontrol.

Любые предложения и / или ссылки приветствуются.

Ответы [ 4 ]

4 голосов
/ 01 февраля 2012

Не думаю, что могу добавить что-либо, чего не касается эта статья.

Обратите особое внимание на раздел События жизненного цикла .

http://msdn.microsoft.com/en-us/library/ie/ms178472.aspx

3 голосов
/ 01 февраля 2012

Это общепринятая практика загружать динамические элементы управления в OnInit, чтобы они получали полный жизненный цикл управления.Я не уверен, что я особенно понимаю вашу ситуацию - если вы загружаете элемент управления, основанный на нажатии кнопки, почему он имеет представление состояния в этот момент?На next OnInit вы должны загрузить элемент управления снова (я обычно использую элемент Viewstate уровня страницы для отслеживания необходимости загрузки определенного элемента управления), чтобы он мог восстановить из Viewstate.Что-то вроде:

class Default : Page {
   enum LoadedControl { Textbox, Label, GridView }

   override OnInit() {
      if (IsPostback) {
        var c = Viewstate["LoadedControl"] as LoadedControl;
        if (c != null) LoadDynamicControl(c);
      }
   }

   void Button_Click() {
     var c = (LoadedControl)Enum.Parse(typeof(LoadedControl), ddl.SelectedValue);
     LoadDynamicControl(c);
   }

   void LoadDynamicControl(LoadedControl c) {
     switch (c) {
        case LoadedControl.Textbox:
           this.ph.Controls.Add(new Textbox());
           break;
        ...
     }

     ViewState["LoadedControl"] = c;
   }
}

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

Control.Controls.Add(Control)
   Control.AddedControl(Control)
      Control.LoadViewStateRecursive(object)
          Control.LoadViewState(object)

Взяв в качестве примера Label, он переопределяет LoadViewState и получает его свойство Text непосредственно из ViewState.TextBox похож.Итак, по моим прочтениям, все будет в порядке, чтобы добавить в любой момент, а затем получить доступ к ViewState.Это не похоже на мой опыт, поэтому дальнейшее расследование кажется оправданным.

1 голос
/ 01 февраля 2012

Я удивлен, но заинтересован в твоих результатах. Когда я работаю с динамическими элементами управления, я всегда добавляю их в Page_Init. Все остальное не работает. Но вы правы - как это сделать, если вы добавляете их в ответ на нажатие кнопки.

Единственный способ, который я нашел, это изучить коллекцию Request.Form("__EVENTTARGET") на PageInit. Он содержит идентификатор элемента управления, который вызвал обратную передачу, например, нажатие кнопки. Конечно, он будет определяться по именующим контейнерам, в которых он появляется. Как только вы определили «событие» этим методом, вы можете добавить нужные элементы управления.

Конечно, все это немного глупо, но это единственный способ, который я нашел, делая эти вещи. Это работает.

Интересно, что ViewState доступен на PreRender, если вы добавите элементы управления на Page_Load. Но, как видно из приведенной выше ссылки, вам уже поздно помогать. Состояние контроля повторно гидратируется во время цикла загрузки. Если его там нет, то ваше состояние управления или динамические элементы управления просто исчезнут.

0 голосов
/ 01 февраля 2012

Вы пытались использовать событие LoadComplete?

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

Это срабатывает после PageLoad и все события (ButtonClick и т. Д.), Поэтому ваши пользовательские элементы управления загружаются в события ButtonClick, а в LoadComplete их ViewState уже инициализирован.

...