asp.net динамически добавил пользовательский элемент управления сохранением значений после обратной передачи - PullRequest
7 голосов
/ 15 октября 2010

Вот моя проблема. У меня есть пользовательский контроль, который я хочу разрешить пользователям добавлять столько экземпляров, сколько необходимо, с помощью нажатия кнопки (каждый раз, когда нажимается кнопка, я хочу добавить еще один экземпляр моего пользовательского элемента управления в Panel). В первый раз все работает нормально, но каждый дополнительный пост удаляет все добавленные элементы управления. У меня нет проблем с отслеживанием количества пользовательских элементов управления, добавленных пользователем, но как мне убедиться, что они остаются в том же состоянии, в котором они находились до обратной передачи? Я прочитал несколько сообщений о людях, использующих SaveViewState и LoadViewState, но я не смог найти ни одного примера.

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

Спасибо заранее, Бен

Ответы [ 7 ]

10 голосов
/ 15 октября 2010

Поскольку вы программно добавляете элементы управления на свою страницу, вам нужно будет воссоздать их при КАЖДОЙ обратной передаче.

Кроме того, необходимо заново создать программно добавленные элементы управления для события PreInit или Init страницы. Это для правильного управления восстановлением состояния представления.

Если вы этого не сделаете, контроль при обратной передаче пропадет, и они не будут обрабатывать события.

EDIT

Хотя рекомендуется добавлять динамические элементы управления на PreInit или Init, верно (как говорит Дастин Ходжес), что это может сработать, если вы добавите их на page_load. Я бы сказал, что вам следует избегать этого, если у вас нет другого выбора.

Возможно, вам удастся загрузить свои элементы управления в Обработчик события Page_Load и правильное поддержание состояния просмотра.
Все зависит от того, устанавливаете ли вы какие-либо свойства динамически загружаемых элементов управления программно или, если да, когда вы делаете это относительно Controls.Add (dynamicControl) линия.
Подробное обсуждение этого вопроса выходит за рамки данной статьи, но причина, по которой он может работать, заключается в том, что Метод Add () элемента управления рекурсивно загружает состояние представления родителя в его дочерние элементы, даже несмотря на то, что этап состояния представления представления пройден.

Источник MSDN

4 голосов
/ 16 октября 2010
2 голосов
/ 15 октября 2010

Если вы отслеживаете количество элементов управления, добавленных пользователем, вам необходимо заново создать элементы управления, добавленные пользователем ранее, предпочтительно в Page_Init или Page_Load.Добавьте что-то вроде этого к этому обработчику:

for(int i=0; i<NumberOfControlsUserHasAdded; i++)
{
    //todo:  change this to the appropriate user control
    TextBox tb = new TextBox();
    tb.ID = "tb" + i.ToString();
    //todo:  add to appropriate control collection
    this.Controls.Add(tb);
}

Если вы сделаете это таким образом, состояние элементов управления должно сохраняться, потому что при добавлении элемента управления tb в коллекцию элементов управления он воспроизводит события идолжен автоматически восстановить свое состояние просмотра.

Вам не нужно отслеживать их состояние в сеансе, так как в большинстве случаев оно будет сохранено в состоянии просмотра для вас

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

Мне приснился кошмар, когда я пытался осуществить это на старом проекте. В промежуточное время я обнаружил, что знаю о веб-разработке гораздо меньше, чем думал (чтение этого сайта - отличный способ смирить себя ежедневно, если не ежечасно). В этом проекте Page.IsPostBack был абсолютно бесполезен для меня, потому что я динамически создавал элементы управления.

При этом лучшее, что я могу предложить, - рассмотреть возможность использования переменной Session. Если у вас есть класс (или набор классов), представляющий данные, которые вы захватываете со страницы, то, возможно, было бы проще сохранить значения в этом классе / коллекции, чтобы улучшить читаемость кода, а затем записать его в сессия.

0 голосов
/ 15 октября 2010

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

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

Но вы можете просто заполнить свой заполнитель, в котором есть пользовательские элементы управления на page_load. Я могу привести пример в ближайшее время.

Пример того, что я делаю:

if (Session["footer"] == null)
{
 Session["footer"] = new Footer(LinksRules.BuildFooterLinks((int)WebSiteSections.Main));// where Footer is my control
}
footerPH.Controls.Add((Footer)Session["footer"]);

Как шаблон синглтона ...

Так что, как я понимаю, вы можете сделать это на любом, что вызовет обратную передачу

Session ["DynamicControls"] = PlaceHolder.Controls;

и в методе загрузки страницы вы можете:

foreach(var control in (List<Controls>)Session["DynamicControls"])
{
  yourPlaceHolder.Controls.Add(control);
}

и если объект сеанса пуст, просто добавьте один, как будто его там никогда не было ..

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

0 голосов
/ 15 октября 2010

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

Что если вы добавили элементы управления в повторитель? Состояние просмотра повторителя может отслеживать каждый добавляемый элемент управления, чтобы при постбеке он не сдулся.

0 голосов
/ 15 октября 2010

Посмотрите на PageLoad и добавьте if(!this.IsPostBack) перед строкой, где вы очищаете панель.

это, конечно, только предположение, но я видел много вопросов, где проблема быласвязанные с этим .

...