2013-10-11 2 views
1

Раньше при разработке динамически загружаемых приложений с одним типом управления с несколькими элементами управления у меня было огромное количество головных болей с помощью viewstate. Причиной этого было то, что элементы управления должны быть добавлены на этапе OnInit, а не после. Поскольку я обрабатывал контрольное событие (например, selectedIndexChanged в выпадающем списке), я загружал их на этапе обработчика событий. Я знаю о догоняющем контроле за дочерним контролем, но я заметил, что иногда это просто не работает.
Чтение значений из Request.Form

Мне еще раз поручено разработать такое приложение. На этот раз я решил использовать другой подход. Для тех элементов управления выбора, которые загружают динамический элемент управления на основе их значения, я проверю их значения обратной обратной связи (из Request.Form) во время этапа OnInit и сразу же загружаю элемент управления. Я не буду загружать никаких динамических элементов управления с этапа обработчика событий, так как это прямо перед OnPreRender, и это слишком поздно.

В итоге:
Какие подводные камни проверки значения элемента управления из коллекции Request.Form в начале цикла страницы (например OnInit), а затем выполняет действие, вместо того, проверьте, что значение из фактического контроля позже в цикле страниц?

ответ

0

Одна из подводных камней заключается в том, что если элемент управления не включен в <form>, он не будет существовать. Я бы рекомендовал идти вперед и добавлять их на этапе обработчика событий - потому что именно тогда вы знаете, что хотите добавить, - но сохраните необходимую информацию, чтобы восстановить эти элементы управления либо в ViewState, либо в SessionState.

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

Итак, предположим, вы нашли, что вам нужно создать контроль. Вы бы построить его:

var tb = new TextBox(); 
tb.ID = "myTextBox"; 
... 

но вы также сохранить необходимую информацию о состоянии:

this.ViewState.StoreControl(typeof(TextBox), "myTextBox"); 

, а затем просто построить метод расширения:

public static void StoreControl(this StateBag vs, Type controlType, string name) 
{ 
    var dynamicControls = vs["DynamicControls"] as List<Tuple<Type, string>>; 
    if (dynamicControls == null) 
    { 
     dynamicControls = new List<Tuple<Type, string>>(); 
     vs["DynamicControls"] = dynamicControls; 
    } 

    var t = dynamicControls.FirstOrDefault(tp => tp.Item2 == name); 
    if (t == null) { dynamicControls.Add(Tuple.Create(controlType, name)); } 
} 

затем в OnInit вы может сделать что-то вроде этого:

var dynamicControls = vs["DynamicControls"] as List<Tuple<Type, string>>; 
if (dynamicControls != null) 
{ 
    foreach (var tp in dynamicControls) 
    { 
     Control c = Activator.CreateInstance(tp.Item1) as Control; 
     c.ID = tp.Item2; 
     this.Controls.Add(c); 
    } 
} 

ПРИМЕЧАНИЕ: этот код был написан на SO. Он не компилируется и не отлаживается. Но ты получил идею.

+0

Как можно управлять сервером asp.net не в

? – BlueChameleon

+0

@BlueChameleon, это можно сделать, я сделал это. Я не говорю, что это будет мейнстрим - я просто говорю, что это можно сделать. Но также, пожалуйста, см. Мое редактирование. –

+0

Честно говоря, я вижу, что вы здесь делаете, но ваша первоначальная ошибка, о которой вы говорили, никогда не произойдет в нашей системе, потому что, если мы начнем добавлять элементы управления вне формы, мы не сможем использовать Control.FindControl(), чтобы найти их, и это сломает все , Кроме того, группа стандартных элементов управления ASP.NET вызывает System.Web.UI.Page.VerifyRenderingInServerForm(), чтобы убедиться, что они находятся в форме, иначе они начнут бросать ошибки. – BlueChameleon

Смежные вопросы