Где в жизненном цикле страницы можно безопасно загружать / удалять динамические элементы управления? - PullRequest
0 голосов
/ 22 октября 2010

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

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

public void override OnLoad(EventArgs e){
    //don't need to check IsPostback, we have to load the controls on every POST    
 FormDefinition initialFormDefinition = ServiceLayer.GetFormDefinition(id);
 BuildControls(initialFormDefinition);
}

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

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

public void override OnLoad(EventArgs e){
 FormDefinition initialFormDefinition = ServiceLayer.GetFormDefinition(id);
 BuildControls(initialFormDefinition);
 if (IsPostBack){
  PushControlValuesIntoForm(initialFormDefinition);
  var updatedFormDefinition = ServiceLayer.ApplyBizRules(initialFormDefinition);
  ReBuildControls(updatedFormDefinition); //remove controls and re-add them
 }
}

К сожалению, когда вы очищаете элемент управления и повторно добавляете его, ViewState теряется, даже если тип элемента управления и ControlID одинаковы, поэтому это решение обанкротилось. Любые разумные идеи о том, как добиться того, чего я добиваюсь, приветствуются!

1 Ответ

1 голос
/ 22 октября 2010

Один из способов может состоять в том, чтобы загрузить свои элементы управления и затем решить, нужно ли вам обновить определение формы, и если да, то заново запустить жизненный цикл страницы. См. Пример кода ниже:

public void override OnLoad(EventArgs e){

 var updatedFormDef = Context.Items["UpdatedDef"] as FormDefinition;
 if (null != updatedFormDef)
 {
    // Updated form def, rebuild controls
    BuildControls(updatedFormDef);
 } 
 else
 {
    // load initial form def
    var initialFormDefinition = ServiceLayer.GetFormDefinition(id);
    BuildControls(initialFormDefinition);
    // check whether we need to update form def
    if (IsPostBack){
       PushControlValuesIntoForm(initialFormDefinition);
       var updatedFormDefinition = ServiceLayer.ApplyBizRules(initialFormDefinition);
       if (null != updatedFormDefinition)
       {
          // we have to update UI, transfer to self
          Context.Items["UpdatedDef"] = updatedFormDefinition;
          try
          {
              Server.Transfer(this.Request.RawUrl, true);
          }
          catch(ThreadAbortException)
          {
             // Do nothing
          }
       }
 }
}
...